From b34b4c3b0ef7ec8513d0ec5f4dbeeef783d86321 Mon Sep 17 00:00:00 2001 From: Joe Klinger Date: Mon, 17 Apr 2017 15:11:37 -0400 Subject: [PATCH 01/20] Basic raymarching engine --- .gitignore | 2 + deploy.js | 22 +++++++ index.html | 19 ++++++ package.json | 23 +++++++ src/glsl/pass-vert.glsl | 5 ++ src/glsl/rayMarch-frag.glsl | 121 ++++++++++++++++++++++++++++++++++++ src/main.js | 90 +++++++++++++++++++++++++++ src/proxy_geometry.js | 57 +++++++++++++++++ src/rayMarching.js | 41 ++++++++++++ webpack.config.js | 33 ++++++++++ 10 files changed, 413 insertions(+) create mode 100644 .gitignore create mode 100644 deploy.js create mode 100644 index.html create mode 100644 package.json create mode 100644 src/glsl/pass-vert.glsl create mode 100644 src/glsl/rayMarch-frag.glsl create mode 100644 src/main.js create mode 100644 src/proxy_geometry.js create mode 100644 src/rayMarching.js create mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5171c540 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +npm-debug.log \ No newline at end of file diff --git a/deploy.js b/deploy.js new file mode 100644 index 00000000..57204bec --- /dev/null +++ b/deploy.js @@ -0,0 +1,22 @@ +var colors = require('colors'); +var path = require('path'); +var git = require('simple-git')(__dirname); + +git.status(function(err, status) { + if (err) throw err; + if (!status.isClean()) { + console.error('Error: You have uncommitted changes! Please commit them first'.red); + } else { + git.raw(['subtree', 'split', '--prefix', 'build', '-b', 'gh-pages'], function(err, result) { + if (err) console.warn(err.toString().yellow); + + git.push(['origin', 'gh-pages', '-f'], function(err, result) { + if (err) { + console.error(err.toString().red); + } else { + console.log('Deployed!'.green); + } + }); + }) + } +}) \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..04f465eb --- /dev/null +++ b/index.html @@ -0,0 +1,19 @@ + + + + Project 6: Implicit Surfaces + + + + + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..737868d0 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "scripts": { + "start": "webpack-dev-server --hot --inline", + "deploy": "npm run build && node deploy.js", + "build": "webpack" + }, + "dependencies": { + "babel-core": "^6.23.1", + "babel-loader": "^6.3.1", + "babel-preset-es2015": "^6.22.0", + "colors": "^1.1.2", + "dat-gui": "^0.5.0", + "file-loader": "^0.10.0", + "simple-git": "^1.66.0", + "stats-js": "^1.0.0-alpha1", + "three": "^0.84.0", + "three-effectcomposer": "0.0.1", + "three-orbit-controls": "^82.1.0", + "webpack": "^1.13.3", + "webpack-dev-server": "^1.16.2", + "webpack-glsl-loader": "^1.0.1" + } +} diff --git a/src/glsl/pass-vert.glsl b/src/glsl/pass-vert.glsl new file mode 100644 index 00000000..748eb5c3 --- /dev/null +++ b/src/glsl/pass-vert.glsl @@ -0,0 +1,5 @@ +varying vec2 f_uv; +void main() { + f_uv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); +} \ No newline at end of file diff --git a/src/glsl/rayMarch-frag.glsl b/src/glsl/rayMarch-frag.glsl new file mode 100644 index 00000000..ee0da11e --- /dev/null +++ b/src/glsl/rayMarch-frag.glsl @@ -0,0 +1,121 @@ + +#define MAX_GEOMETRY_COUNT 100 +#define SPHERE_TRACING true +#define T_MAX 40.0 + +/* This is how I'm packing the data +struct geometry_t { + vec3 position; + float type; +}; +*/ +// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT]; +// uniform int u_count; + +varying vec2 f_uv; + +uniform float u_time; +uniform vec2 u_resolution; +uniform float u_fovy; +uniform float u_aspect; + +/***** Geometry SDF Functions +http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm + *****/ + +float SDF_Sphere( vec3 pos, float radius ) { + return length(pos) - radius; +} + +// Return the distance of the closest object in the scene +float sceneMap( vec3 pos ) { + return SDF_Sphere( pos, 1.0 ); +} + +// Compute the normal of an implicit surface using the gradient method +vec3 computeNormal( vec3 pos ) { + vec2 point = vec2(0.0001, 0.0); + vec3 normal = normalize( + vec3(sceneMap(pos + point.xyy) - sceneMap(pos - point.xyy), + sceneMap(pos + point.yxy) - sceneMap(pos - point.yxy), + sceneMap(pos + point.yyx) - sceneMap(pos - point.yyx))); + return normal; +} + +// Check for intersection with the scene for increasing t-values +vec2 raymarchScene( vec3 origin, vec3 direction ) { + float dist; + float t = 0.01; + for(int i = 0; i < 500; i++) { + float dist = sceneMap(origin + t * direction); + if(dist < 0.0001) { + return vec2(t, 1.0); // intersection + } else if(t > T_MAX) { + break; + } + #ifdef SPHERE_TRACING + t += dist; + #else + t += 0.01; + #endif + } + return vec2(0.0, -1.0); // no intersection +} + + + + + + +void main() { + + /** Raycasting **/ + + // Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182 + vec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x, + gl_FragCoord.y / u_resolution.y) - 1.0; + + vec3 cameraPos = vec3(0.0, 0.0, 0.0); + + // Circle the origin (0, 0, 0) + cameraPos.x = sin(u_time) * 10.0; + cameraPos.z = cos(u_time) * 10.0; + + float len = 20.0; // assume the reference point is at 0, 0, 0 + + + // Compute camera's frame of reference + vec3 look = normalize(-cameraPos); + vec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector + vec3 up = normalize(cross(right, look)); + + float tanAlpha = tan(u_fovy / 2.0); + vec3 V = up * len * tanAlpha; + vec3 H = right * len * u_aspect * tanAlpha; + + // Convert x/y components of gl_FragCoord to NDC, then to a world space point + vec3 point_World = point_NDC.x * H + point_NDC.y * V; + + // Perform the raymarch + vec3 direction = normalize(point_World - cameraPos); + vec2 isect = raymarchScene( cameraPos, direction ); + vec3 isectPos = cameraPos + isect.x * direction; + + /** Shading and lighting **/ + + if(isect.y > 0.0) { // we did intersect with something + vec3 normal = computeNormal( isectPos ); + + // Lighting + vec3 baseMaterial = vec3(0.2); + vec3 sun = vec3(0.5, 0.4, 0.3) * 12.0; + vec3 sunPos = vec3(5.0, 5.0, 0.0); + float sunDot = clamp(dot( -normal, normalize(sunPos - isectPos) ), 0.0, 1.0); + + // Apply lambertian shading - for now + gl_FragColor = vec4( baseMaterial * sun * vec3(sunDot), 1 ); + } else { + // Background color + gl_FragColor = vec4(f_uv, 0, 1); + } +} diff --git a/src/main.js b/src/main.js new file mode 100644 index 00000000..ee9d2287 --- /dev/null +++ b/src/main.js @@ -0,0 +1,90 @@ +require('file-loader?name=[name].[ext]!../index.html'); + +const THREE = require('three'); +const OrbitControls = require('three-orbit-controls')(THREE) + +import DAT from 'dat-gui' +import Stats from 'stats-js' +import ProxyGeometry, {ProxyMaterial} from './proxy_geometry' +import RayMarcher from './rayMarching' + +var BoxGeometry = new THREE.BoxGeometry(1, 1, 1); +var SphereGeometry = new THREE.SphereGeometry(1, 32, 32); +var ConeGeometry = new THREE.ConeGeometry(1, 1); + +var clock = new THREE.Clock(); + +window.addEventListener('load', function() { + var stats = new Stats(); + stats.setMode(1); + stats.domElement.style.position = 'absolute'; + stats.domElement.style.left = '0px'; + stats.domElement.style.top = '0px'; + document.body.appendChild(stats.domElement); + + var scene = new THREE.Scene(); + var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 ); + var renderer = new THREE.WebGLRenderer( { antialias: true } ); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.setClearColor(0x999999, 1.0); + document.body.appendChild(renderer.domElement); + + var controls = new OrbitControls(camera, renderer.domElement); + controls.enableDamping = true; + controls.enableZoom = true; + controls.rotateSpeed = 0.3; + controls.zoomSpeed = 1.0; + controls.panSpeed = 2.0; + + window.addEventListener('resize', function() { + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + renderer.setSize(window.innerWidth, window.innerHeight); + }); + + var gui = new DAT.GUI(); + + var options = { + strategy: 'Ray Marching' + } + + gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']); + + scene.add(new THREE.AxisHelper(20)); + scene.add(new THREE.DirectionalLight(0xffffff, 1)); + + var proxyGeometry = new ProxyGeometry(); + + var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial); + var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial); + var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial); + + boxMesh.position.set(-3, 0, 0); + coneMesh.position.set(3, 0, 0); + + proxyGeometry.add(boxMesh); + proxyGeometry.add(sphereMesh); + proxyGeometry.add(coneMesh); + + scene.add(proxyGeometry.group); + + camera.position.set(5, 10, 15); + camera.lookAt(new THREE.Vector3(0,0,0)); + controls.target.set(0,0,0); + + var rayMarcher = new RayMarcher(renderer, scene, camera); + + (function tick() { + controls.update(); + stats.begin(); + proxyGeometry.update(); + if (options.strategy === 'Proxy Geometry') { + renderer.render(scene, camera); + } else if (options.strategy === 'Ray Marching') { + rayMarcher.render(proxyGeometry.buffer, clock); + } + stats.end(); + requestAnimationFrame(tick); + })(); +}); \ No newline at end of file diff --git a/src/proxy_geometry.js b/src/proxy_geometry.js new file mode 100644 index 00000000..c100b827 --- /dev/null +++ b/src/proxy_geometry.js @@ -0,0 +1,57 @@ +const THREE = require('three'); + +export var ProxyMaterial = new THREE.MeshLambertMaterial({ + color: 0xff0000 +}); + +export const PROXY_BUFFER_SIZE = 4; + +export default class ProxyGeometry { + constructor(bounds) { + this.group = new THREE.Group(); + this._buffer = new Float32Array(); + } + + add(mesh) { + this.group.add(mesh); + this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length); + this.computeBuffer(); + } + + remove(mesh) { + this.group.remove(mesh); + this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length); + this.computeBuffer(); + } + + update(t = 1/60) { + const {children} = this.group; + for (let i = 0; i < children.length; ++i) { + const child = children[i]; + // TODO: animate objects + } + this.computeBuffer(); + } + + computeBuffer() { + const {children} = this.group; + for (let i = 0; i < children.length; ++i) { + const child = children[i]; + this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x; + this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y; + this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z; + + if (child.geometry instanceof THREE.BoxGeometry) { + this._buffer[PROXY_BUFFER_SIZE*i+3] = 0; + } else if (child.geometry instanceof THREE.SphereGeometry) { + this._buffer[PROXY_BUFFER_SIZE*i+3] = 1; + } else if (child.geometry instanceof THREE.ConeGeometry) { + this._buffer[PROXY_BUFFER_SIZE*i+3] = 2; + } + } + } + + get buffer() { + return this._buffer; + } +} \ No newline at end of file diff --git a/src/rayMarching.js b/src/rayMarching.js new file mode 100644 index 00000000..e0fcb507 --- /dev/null +++ b/src/rayMarching.js @@ -0,0 +1,41 @@ +const THREE = require('three'); +const EffectComposer = require('three-effectcomposer')(THREE) + +import {PROXY_BUFFER_SIZE} from './proxy_geometry' + +export default function RayMarcher(renderer, scene, camera) { + var composer = new EffectComposer(renderer); + var shaderPass = new EffectComposer.ShaderPass({ + uniforms: { + u_time: { + type: 'f', + value: 0 + }, + u_resolution: { + type: 'v2', + value: new THREE.Vector2(window.innerWidth, window.innerHeight) + }, + u_fovy: { + type: 'f', + value: camera.fov + }, + u_aspect: { + type: 'f', + value: camera.aspect + } + }, + vertexShader: require('./glsl/pass-vert.glsl'), + fragmentShader: require('./glsl/rayMarch-frag.glsl') + + }); + shaderPass.renderToScreen = true; + composer.addPass(shaderPass); + + return { + render: function(buffer, clock) { + shaderPass.uniforms["u_time"].value = clock.getElapsedTime(); + composer.render(); + // console.log(composer); + } + } +} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 00000000..12eb33f1 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,33 @@ +const path = require('path'); + +module.exports = { + entry: path.join(__dirname, "src/main"), + output: { + path: path.join(__dirname, "build"), + filename: "bundle.js" + }, + module: { + loaders: [ + { + test: /\.js$/, + exclude: /(node_modules|bower_components)/, + loader: 'babel-loader', + query: { + presets: ['es2015'] + } + }, + { + test: /\.glsl$/, + loader: 'webpack-glsl-loader' + }, + { + test: /\.(obj|bmp|gif|png)$/, + loader: 'file-loader?name=./assets/[name]-[hash:6].[ext]' + } + ] + }, + devtool: 'source-map', + devServer: { + port: 7000 + } +} \ No newline at end of file From 71c59b744a8407bf4f8ba1e494b4393a23f7e96c Mon Sep 17 00:00:00 2001 From: Joe Klinger Date: Mon, 17 Apr 2017 15:12:46 -0400 Subject: [PATCH 02/20] Updated index.html --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 04f465eb..b5f3f4e9 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ - Project 6: Implicit Surfaces + Final Project: Fractalz + + + + + \ No newline at end of file From cdb2c8821274c3f5c70824a719b5265f13cee21d Mon Sep 17 00:00:00 2001 From: tabathah Date: Tue, 18 Apr 2017 22:40:36 -0400 Subject: [PATCH 06/20] updated milestone 1 readme, added pictures because deploy is buggy --- Milestone 1.txt | 4 +++- milestone1Pics/milestone1.PNG | Bin 0 -> 565011 bytes milestone1Pics/milestone102.PNG | Bin 0 -> 562312 bytes 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 milestone1Pics/milestone1.PNG create mode 100644 milestone1Pics/milestone102.PNG diff --git a/Milestone 1.txt b/Milestone 1.txt index 2e736440..a4c9f31d 100644 --- a/Milestone 1.txt +++ b/Milestone 1.txt @@ -4,7 +4,9 @@ Joe fully completed the ray-marcher (basically all the work of Hw 6) and it seem Tabatha got a working Mandelbulb to appear in Joe's ray-marcher. It took a lot of time to understand iq's code, cross-reference it with examples on shadertoy, and tweek and experiment with numbers to find an implementation that made a Mandelbulb show up. With the remainder of her time, Tabatha set up a basic, but aesthetically pleasing scene with several Mandelbulbs rotating about different axes. -You can view our current demo at https://github.com/tabathah/FinalProject. Note it is extremely slow and WebGL might need to reload, but it works! +You should be able to view our current demo at https://tabathah.github.io/FinalProject. Note it is extremely slow and WebGL might need to reload, but it works! + +If this doesn't load or the deploy didn't work (because I'm not convinced it did), there are some images of the scene in the folder milestone1Pics. Things that we did not foresee that we definitely want to improve for the next milestone along with the plans in our design doc include: - possibly optimizing the ray-marcher even further, as when a single Mandelbulb is in the scene, the FPS reaches a max of 3 diff --git a/milestone1Pics/milestone1.PNG b/milestone1Pics/milestone1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e910bf6b1f230b5d869d73567d9b8085b8b08680 GIT binary patch literal 565011 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⪼%A&XGtj! z-GorDGUt~N=)PM=L;PTFntNIAPIA@Dl1{zpv(@CC6mZ;2UXH&|xSKWm%I&A=(Y|-} zD7Eya9Qx)s2>}hu?foxo@-&!?rxylIYZG8mpij4kZUv`$U`Wj}0EKCP)SPCM1nRfyKa`LE zJO;j3K7L#JeH$Y0%`umLudlv&YSs{Jp&Yh=kTcQQiV?H zEt3|wm?D1!(zLd9%!|*zI;TUFw3xUYiG8jAYMU8s_Z#+pzqESjJ~NVf+QC$x@kbul zwtH%pn{hYR+q|S~G)Sulw^N?t!_@o9Wt63H(<4TC!pC@TULAkLbMK@DP0_@r7!D=c zOC8UUy?lu8SDM%cxsgL3o$OTVLZ@)^T6WC7%coY%yvwg6KD&ISI20$Xv>2nJ>e}GC$*A*lhgjrhLr>;arA@LbGZ%??Yq@1BMR-~>~yCEe?Tuc&z_1-{g zpW5puTaj>Xv=I?DForPiU{mmpj0yERqEgP<>SsaCa@H|-;y~vhK(NX=A z+I0_Q(K4wekVRCbP;Q`RBDG4<-UXIRQ2E8B z=#4X~VP4g;WEI#mZPz#6$(#~gqpQ)hWwwv&+b2ZCJ6l>2PHjRaxhQ+?jqQ=+((B&Y zRt6$wyL5u+tg8>^(JRBkyk{O!S$WPJ%a@Rc-AaI5D;U>c=Mn2y2tVpu4WveU&37v@ zBaU^fy(vymmyN@4q*x4#E~?N$1OxVy*dE1>;A218?i3Jf2&%c@8}0C>eD^u)4dG*G_?eOtBgw)i`;Jt#EU6U)C)1`HH zTUTm$hzkwuSjDlF>@XDlrDVl+Wx)(fvFtq6iSkNRDxL8J=1;+BNjV*$+a^7ZPwDz8 zX>W)!lA5#8^%6a`4auH7fZ3vu*S32x#oh8MfZ(XM=Cd=uRvWhh#gHt0GOHvqHL=?_4vugbT5`-W)0!Synwb!mGC zBUIPJJ^%9CcH-~`!1&`VZKpA=>Wa8~U3^a6Zi4ts3NG@kV{An%jNfLC}JXR)~(oIq>gAF@+{1h zic&({yN#0MO6Y0($Q$n_ee@1@$gLTDadLoJZ>-R6RatM6k6W7J>TT(dI+jeTstL^S zL=ED1!-t;sWgxxnS)1 zxz6=kx$~!Ph}^Vrj}}!tEv~1$eT!M~TFC&XTh=v|h*Er3$Qo^G-YdxN)WAsp~ESne-sQq#%s^_jORoLm*Qb1Vpq?)K(3 zsaSTiUtGR*+wN|gl=$;X&!Th<4eJ5dH$kZ73U05NN)(%pg45BtaMv@(Jxnzav#$!& z56M0#3zs71XnoW^Ei-)V;7PkR{EF^xchj}S?1@v%)-&Tn9+Qv20Sy;0yKaK5b({WJ za1AA-ujwy-tAn1?dxtw#yyjqUcRy~4wrdYn3=Zb*k(yyO132BpSP>w3$EiwVNmm{ z?#81fiEC!ZM!0Pgpbn6nnc%_il~koitHR3-_#;KSjyI7 z%uvcwq%p2gwlv0AvQ}n@mWvSDB>P}6mKbG=iYUwsp+RLSvXeoItV4<{Gla=DV;yV1 zv+I7Y`|4Wm<@vpy`}uxf-+y}bVw?=`^ZhyA$8o%mv+jWuVt-&N@g{7a`4)_L_yvjT z;`<7?W>M_@Ue?QR?V%JgV%}udJN3PdPM<~|O{)*=Y{9iL*Q3yH|7r~Rm3#aJRX*wH z21>{B+Vwy1p0A_eD&;@c-mhO3@kHYvm+mhG_rs?}kQ;S22YUm;KS&qrQMU8Bb~}&g zrDFTA9ao4N(#3`pMLyRa=SjVOY@ct3FY%Rhaeca^*0kESadhRjz7m>SxbJLnQ@Xa+ zwEDGK^xC$*Qd*wgnonOy$5%Z*EW)EhkGMk$YeG5BC;5TNLZ7=(c5dbHLlo~VIUVS& zX8DNqjC+c)Mi;|Q;o5e_U0!=(2Ua*&N27!H%OHsD?!_m8za4=gmVVY_(w6th3%6Tx zNv|;RE7QK08!Wd{%HB^HY>Q%Daw~nxHg$XcQ)cRwivim>iI$1cEGRVx78jg1%*-31 zTulwdjN|dC-2ws+g-P@5Ez+mVy#}ND8{2f8*Ep+1^jRMH#iGJ)-=V2qS!9XlsAU7C zaDZ(l9kfYq;Bfld^GW#|pT9B@rXhY3Ki`@}hP)g`R&1j$bKN~5?_<7h6PcN*535=D zz|3OVNu#cBeB@hhoj>usPew^rzo=@b@mX-bFgOp-BW+|5fe!R1GK35#!fZO#;kd(FUat4wcgGSRL(F6+1 zuOVN2p%vY`qavTS816QK9Z65!I`Em9q*v-&;o31xoY{@NN~zpBFu)|~E&EoucWe-) zb}w9{+}^7FnR!nyeup)US)>>57vR{DKqT#1z*4Sm)$V7O>$Up@ICR7i?e;9prJqAo zBPL4F1-AjJd-R{peSdXN{xgl??^NyYJ9}D(=&l3U>pBz6+j{yC9Zj)|T`C7l3_S#! zT-X99CA3iOYi*!2@i>N}Z)B#OjLHQ~V|;W(Q;U%fFlEJ-B_<#Fv|~~zls{}=T!r3p z(AaUB=g_Ks%e2q>6|FcNK(X7rrfelaABmi3{G{w=&_1bziG>W=-c(fK>=ikHZ-u(E*WPXl0EGW@H;^Ffz;2%tnkXaFAgJWS znmao|jpgJqVD#6erzoE?B5?uFm}xw~9c@#418T*UTzHDb#mX@rD9(8Sf^P@1W|&9m z`v=c99V4!CvU)&`Wjb-$69klh^9~xt+`F~e=WVZX0R%|Oh31<{`4Bu@p_7afeHDzQ zo;+91*S?5QbP-FcXLh8=M-X9)?TceeC~uzxVZJT0Ps$=TbQBQ+$TJgJtc7?kF~bBw zqJC}vamoep#Vj!SlJgN$^ITVPB=d#qr^TXuz2yf*5&J_iMj3e?t!HD=D}5@@>^1FB zSMZ9;;_VsQFerfChrV5Pp#$NXe^#J;{r-S8{u(O$tMmW2BKpVV!T(Rm>z9)u`jpb| z=&&NOG~o^bY3?IbkY;y1Ecjwo1>dQY)FRw^m^ofbYJRsa3DRC}bsxPqcO%i_q=)*64F1qB6XTnvZz#Ox z1~~&;$ky13)%zRGvzErs!5bW{k=e)`3dj(rz)2jLzQbQIFc)!L21#TwY$(gKFMpom zF<~*oTaQk*@|Wtl)+Mp9`?zRAdiJik;XPegc#0mFscPAI=2sPEQ#X6Xy)8j5l1?S2E z(;lN;xi_x&CWo*P@W3UrJ#{iM|3SH(SF7X7v5u%htKgmV+2h7qjpG^8+CBl>hOCln zp1Xlbq3GPLXQAhk=n2PnISQqR7j`oEhnbb!m=+`CnbOZi+t4ZDSsId^#oI{ORE?_H z6Zxirk`DoA9!4COw7>I(gl2i4(^pT?hs`T*k9`SVYWDw!B}oxW>H85J{LsGs{qFVy zPWa!^KH-|S!F422M0R`U&IXn1g=$}O-@pb>Q&0yD}ZwyEZ=#X0HcplJEiL51zoUyrOZr5zsGTB?gm?-`K#|TJ^KHUhiVV*OmA&0YaIZO4v)5>yo2G$G2mcKEt%<`>Wd5 zmIko_-%vSR@(fEJ^RkUN{_K_n`+&)XdwvDAp=YLwS>7_-P=)VLQ!k1yyUh=ehF1+f zGt3Eti(5g>_~k?c5_=(qhj>J(QE`Kh*v_|LS&$g-ZcASIC;Sh%@+7xJ;I?h`0Q!B; z`E%cbp12(3EF8@51MK1zcQwM zz(f(GA)ZQLOh5O{w7~pC^hnDL0!eN$-LuV^?#xBZ5+jLqM1k+~CiDp^FkiWmm;Bp^ z?a_3BpqiU7E|OrRS5>gucWcvpmGGE8AN31Shp*BZO)B6Iumku9=zN zRL$QXmH#b0=(oB5Bx_-#^nXndEpJi&n7PNt+{v6fN05xxI^cLW3?dD=bKd7!VL@9D zb);mzRG2J-d{9mlL9qL$@>^KEg=PEeA^Wetp)5R{3^gZgKgxZ=xCa_4f{$h;>KPdK zc?9o&3@OYEqaa^IO)Rj!7@w0(>snno#)ik?n@c}u_tSZky>Q4|6#s5ZE=s{7o!KZ+ z+IUT#Fj6W@{ES4L523^RoBCUDLW7;{n+eQ^9c;RLoNds%ye%dTv$uLvO1nI<;&g%D zs&%C~7hZTHg&!kMUhtuI2QK$v1C&{C?nH5}lIzFx_kT{h-KzsUK>3_iiR;Yhu0aG* zEcnAKn!Pp5*GPVUBDd8W*cGFPjV{s!-(>Xf?29lDyQdYb#iyW-5)Hj?fvNhEe@ZF% zw8G|*o&gjs&-a*`xg{pmV_FR1T!~F}oITq(W({Ar;y{Cg&)Sz> zR_{F_4apcSiK$k1<8oYBrTk+ygZLQ)2@hA z)Y~;|xkXO=IMlEv70^Z16m=6XChVOihz;i|)?0{oj@tER=O;4)BNnY23ZGIYgJ;K2 z3YGR5;zY0tEP~3CrbL%ZPD!t&rN{O9#pCpkrNhWYjYgal9nV4(K&USCG)4}Eb@W#7 z5?}Huoi)9$DXgmLRARm))|N8KH_*X+qjz+BMLA6|+-(}$pWd%EaAcwl?YF(6lBOL# zGmRZeU(?b)JW+?ASS5 z)h52^6<`B=I$Vf$JD*3u-u*MR;xCZMKNYn8y6szIqxlnIU<|)nz3@GgjNCm;LL2gi zR8bjgR9lD}xFwX>TW zC5~fUO9dE)0}KgvaU{mS0b&yhOEN}%>7TK_;CNxE293XNj0C3$A|o!}q;$lbBWqT3 z79o^mFF{L9jku?oC;CfarO~tPC&6fJ02|tq*YQ7HF^a37EA@H3;qM#DLT1)-m9Wv#xe^B2rH8dWFub zukA-W#(^zBc{FN>UmtV-FhpxjyAlU5V-14&qmxyjpA>Tl(36hh22k5WPcGrSCJ36% zrZ6$sZc$vc{ELLs1un=L6ZvWVxrq|ZnUfBOoKNfvRxrme5HEGTlVZzRNNmAO;tQH@COE}fvw zXRCd~*2OHV4goGaKl;9%mSUW*e(NH(gCOu(JYT&1DDurpl1ms%)nTt~(_An(P5(;( zA$aL_4Cl|Y&#%9|)`80PEk3S1uX3fQl=7Sh3|#W&6uZp^q-?Nc+!V z+doo!MUiNg=5&y`LAv2?Zr(E;iLxRYDqe8u@TREJ35S{_{GqdB-U9KGNG_rR03+^e zI$p`xN)~2EiH0`wpK+^gX$6%;VgyJckx*U%Fj9*184$_mpZn|)7F-+lBv1;w-@S3U zkOzYpdurFOnx{-UOR)`Z$Q+;_`!IhDxLK~?WKfC)4te6e&NpG(u7Dai5kbhf_EhznF3r`?Lb;J=s*BsO9|C>jK%%wc%31TSq89{ugSRFvovm6} z^Nu3N8e3o+lLI zv>j#Z!SEGr6Ah&dmu|IM?g#_36WP93*N;7XM6X<#X+HZqc*x=?m!4Aik0;wxvw-O&`A2gx1>L zS58w3_nj{8Pan{lK60%c9k{)(l7XR0PP*n1`=Fja%OYJ$-Po}=O+eEjhvv&MGE zVaVkV%z?lg5?o)k!RcdQb5-3|{s_4bWayHX+|MIGLd`LIaeN zgd>92!I=wXyCS^5w1<(WsUCOE>z6l{7kzc%!Q~aSQ`PTJ7JEDg8T*Tab1#&pT_}yQ zv-YcyPdj(vR`aHVWWE1|*k0<0PT+bX^J@GR?Db)0Ey^w)cl!H{JV^N>o6bv2qC#9U z203UgoOaQEY{0hgrDW47MfRMr%N0VhQcHt>PukHhg9V+nye%HE?ud6TNd= zKq2jTxYW$T+jL{T=gftV=}lVNM<(8(G1~(wXsY3)>4nef<66~+CmPYp+XMVNej?fd z$_=IWxC`C%&v(He8~rcc`=Lz2pPT!in6!^sfH~v$EjcLzGH%uB9w!4WF%)(r?EiTe z9pDT1eCdw6L1jC&t`-ONk(dD4 zwocw3HDPc!Z&)B`BukKl+bi`!wu;YvKp#ff*#oO8b6b%VA#t=UaSWtQRelkk=y?Zh zoRk63BXv;@k_EL4TF{DLMlIQ<7H6`ql>^F)4NH-g=SqVT2fyVHxpgRHfg)7S114y0 z^I1FhRTC4sz)+Ik)Y{Ql4%TR^ybSc9Tl`SmF2qk4oD7o)KeaZ@g3n(MRVd^Zj>3gm zpkr8<+zVPbSaHZceIX9v5^o}E>{^cCW2#8g>mrXEReYf)AqOKUUN(;hQ_7%YVr&8S z>Y-}%c2u^@n=zN$lRivwEjgSc=t=CUsmH9qHChvzw0VdZ(0ZddiAKoQiNxWkpeNKE zeqhfH;28|@%@f6;nB)Qwxkk-wsJtr^BBN<&@J~HX5-ex2m118GThpF>R<8&7{+ePb_JLnsibU@wKxD$WY zY5&W4^+De<^+&z!mkIE%QRxpY`fsS>`!xBRl=g3_ZhvdxfAoF-aqQ$n$G$E;blYqX zP(HseSqUVVc(}llJEMwMSp6_z@v_=!8r6hSsJ$(dOJU3y3UX;=Sc(CwM&970V1B#UcZsG=KIEgVs zSPI7gCxXu#h7Yo0%g0h@r7*6 z)ET zuC((4duc7vqr6nzc8&ucZZ|f|P?W-H(-Yq&j!B50u zur|f46y&!Nm-*ETKa-PJH~qD4WB%}m|BYYxD-z>>omJa<;p@L;Fn^tG2fPsw?Zppw z5AX&`CKk$td@&PP>(#tD{{~ANBbeTPeM@{AJ15b`t|xYf@z}n&Za^&_`1D>itI*T_4Mnrp z5@^VURs+_(hi+Q&15$7_B(CWm#<>kfg?L1P)6QQ|W;GlG7$@THO3BR3FJXW!ccF7NMUtgooR)RdVkcSWG;P_FZTTII2Y6xKpBQMmkt>cuDjQ^a0u@2c~JBt zZk1Xy>8?-WL#`z-V|RUc)TViTTrj;2;r5hS1u2COcg4-+hRO|DYmnAV56gv}xViw; zpmri7&1_40D8~Ptt9aZ^Z>95z?#cD-6c%=H&F>}03X~_lVI_&lH>*JDQp7W+K4ZM@ zK$%byu38Wk;RGbXwAKS3Cv`5f&`bl)O=8#emgq-S-v6pW|G8aMX? z3H+xK?JrL8f7r?YCS_OylJwuM_?vSA*ifkcUn1mAtxl~}Qv8W?r604w7`Q(4h@gqV z1sPQ1oc9)3m`EYl$t?$D?kfqYl$V+1bIaQ%AK_UW_K(@Cj$H94;e@25m4k)sRJr`$ zJkivL9k(i1Kh)G;cYWWx(jddncUMU70rMFe0GtYdsZT@`OlBM%0GJE~+Jf1SFBU=0=s3NaBuJm-u2tT26VAV^_vB+N=Aq6{&rfEy zH1p>O8*4XC+T>5ho+Q8;di#1up8Kx!Z)I!Nyy>m?#(HsPMbM6>$5+H*1$^zZK z1VD&Zk!GhdZoxmwS2T>O-*_tDr5GMH6F>DT11IHBen>L6k$k89=S92u8UTI7H1%># zSV_vx&bB@1mzQvs=!8m-k6%6(3PX)A{uJ-oGSHaqeyf)Le-&Wv$5%1SC=B7ot=LT!0QhS@m9o}`G#@Vsp zR2sc!9aw=r)l2_S6^YSR_;gE@AQ&&3HhM+Pl+^%6RBcg~G0Bni310!m53k;_VQ12f z^~`xZTAa*}**!o2p;eKOz!>p+{OATbL%BipuF_=p%9sLs)!R-iF;tbbu{PHZPsx$# z7=PYJ^%Sh4s_vI@a2ju_8r1@h99J&@&ho@Mfd?D&vvNsv=3QbhdB=9c&}jZen=Pa` z#DXNP(s#fE;dnH07|x(c?M+s|3$}8sLR{?hQ4*q@K?lGC901lxX zQ2v;M*OQEQmQ0AyzfA1O;z8W{&_828^RW3ksWHz=Qz z)t@|_^z3*5YX9&bB;>y)CjJ%h_#I*QZ_>U+C9Lj0Q-4343I7s{|KX?lfdKqhBMxdUUa@iIrvhMm0P{xW|V;MCsGqmX-Ls!hrX(Z)Z6CN9aQ|j#V1ZO53H2z z6nLG;f@fH2GnkxM6ICSqpr^iP+$Dz7%t(ho0pum_*;Q)bfJbn}lIQ4d<9P6_ASwgv zA_>M6C>q~muA^OXwkIL+A?X*TpN>V!oB-?<>}9X{T|1)31K*-2cLDY5^VS`0EH!6C zqgT2K)0wtlk~Kch7{#o@^h{88pup*<^_iil2|^n`pef)Ho5%NJD3aws!z%%a)@5_$ zh?92^QpPG^lA0SNS)9nK3blCiIB(YnVkdLN=1bHEQS$n8 zKOy1UDU-qldYYTkL!L7WFuz;W7aJ?0>4mN2L4P|^0X)$?^>~1*0xn>}Qs7?Ry_2m+ zdj({U0Be%$X8GJL_>@|<+e#Wn5vk5ed^orF1_<USS9&kZ2oI|c1$n#CHF2bonv?B(@0KnsUkSeTwaTla_GEm-w9PhsBuYxl z{JJ#cZr^l(L!hmO&g~zX763c{b7d?DbkN^j|34^2^FF!!H_!vDo1~;=5(PEc{^1s( zFd|u?5Sq*`$|om-!&KG}Jq?9$LruZ))V23_6UnL)X!pLk>3ad@f$M^44Z)Uur(AVlsb#x)00C{mfUNs4M!f?lCuTZ zteXW+i8OO2!D4;8T)TV?DCY`}`8(`&YwC2Yx&pjdIKx@#P5||7kyoYd_x2xtzy6@& zAmgD$ZWyIXImNy1WG&=|&_l!}%HruT%*x=LnXhlBxVIZi{c;`n2 zMnW7=vv*x(QN-YGG)-Kb?9o4PjPs#VxMtB!yh0ucPAev0u5@E|Oo$Z0!xLmqimzm4 zl4Vdm4{R1yPJ7y<{X};z8hF}?W?z*<0t+8KZvngh{1Keu=5W$W1^j9-Zj-N+q`uLa z0+HR}a7ko!M63O0&dRr`nR$S%2tyae2%;KYXAtfc6A`7DkR^^OZ6{e5h6!2AiM19% z%1E?^8W^M;5txKn1C(cp`)3`V#0bDSynDq;>h|Rri{uCwq#@Rt8-r+ukG(dP<~dKj z|N8W6Ij0lw+Wh{;rfJ`dt%f3i+Jv`_>zrv{R%-HnwcS1-X zu~?E7Qk!g_3OLD0ktbC(<*qTD@-earV)r7`vsewiKjEVLDZNn`XSMDsv(HKrv*oPd zfak&_2-6x%4T!~_n7>?Idn0)aC!=tOE+9J9(rZJ{t=O)dG|UVNbVW#3jRer@8YsVT z2>LOcVuw0l5>xr!g7ZLmbujL3CcV}kYcw&@W1}<-L2M4YQdG${Fb0G!K-?I#b$Sh$ zjkco%kWAMrh&ed7mAvCgDf)5Teq@H)DxA>dKftXoaLDtLWkAs2R$JCh?Yzzt1X4>Ee2DQ8n5yu3el{9D6A582QqurFV<%nQ#kH zWW*$r8A;*X0fH?hz8nCERiWYgz3?)tyAZ~tQ2!Uf=zXtEZi)CEdY*Q?&6QRYk5X3e z&-j|wH!87fQ0p0OW7od7>79k5QpfodqV*C>i$X=1&)QLdQ@I8plC+JtDp3XJk|_|p5z4hJQMl~Hm}k? z#Mo-2^`(DmxADhxKGZV(3gB%k=(VT@&9zefLM{U;KVN854_|jq8CvozXyPryiA;y3jb7E^&*MWZLQD9Yx1=(b_{n7 zo&uVa$^N{H-KTLCH^8Lk9LhG}>mw)+h7(Zsp?hyWe2{J~B#V#jO`6#oJ$}FaDsydg z#A-22NE1e^g!b7rBCqGQCOls^Orm2MfsAK%k^z0ux z^A8O4cLwA)41NPZTmO_S`R%3O6H9)W{Qks;|BaXVjp_!zkt|^IM+A*k*;15A*x`l7 zgq^Xh?yXpWquYHlIF(orL&i_;-KKxJq4SYIT3)A_IB9oiBq$;%%2@D(bwKS(i5lDA zx}d*tr1=<#)GUD!Pk=_NMI4ZU@~D-tfF++kQd1{bdtT8&)lD7+))Y1x29YI@B?-~0 zhQI>);1#~})KR)grzsDzM6){#!lPLNcq6*r)j>)zvYF`E(j{QmI43a_5QG~j%Wvd* zOITSsiTN%(n2ciAoIa&0u{^eb9Nw#T?+w2ZQ9fWzM1XXuo2HZ-39xl%qcI5X>&ywt zHVcUrwR)P^Yv>k9ex?X%2ds8W(&*POa;n z`GsA^s*RU#!5EfyUtgUk1yVnF7K{AE|A6P9C>G%sGw1C^NUo>M4q)FboLdfYTn+DU zOWBN`fC9F$H^;AmQ#9w`H6LCl#9isS;&J`HYbZt(d4^+EZ`qK^ZIYbipBB8ZkbAlR zY0bP48`tAG=NnLIdyM3m7#rr5NzC6Iux9~G=hr&R2m35-VibiUdINC;s4?)XbC5oi zOo~s6x2$f`Igoa4`_VJ2b~77g#K-2!+zI_V3raveS}1#$mho~i67r8A;om8^e^o`l z6&WC54+XW1TDy0whHFd|)6?%DT#?rj(5XB6p3%m_UriK$Nq>%T)xMUB?%&auPg@H2 z-CgWNA#R=i?3}Du>D%YpF+*J1U3`^Ny>)uPnXI?wYps5*7QMF9T6-cC&9?)QL#qql z!Ngws&hD_Ycw~?z!v?X}^#nN$?k{bog!OWvubKkF;*HkflaZ$!ejbYuQFFvA+frs* z+&@2UlXIucp90LmdB(^d^DMfLlITN#F7>}Zw}&)_lNhE+Ue;$L^NcKxdxXc|-1nMt z*;`w&9@b5T9NfjHLjRzlyOS-@zH1l`B;D}BlvLHS{fS*BuxICR3Z)+f5D(^1U&>ZA zb0MamfyA;e(iG7X>J>H zbuV?AfEQHeIKe`UYAq}cl5>`}Tkunozji)IwK!GGBEUvq!JM zCqTPcjC9}!IQ@${v*+HsFMr4Hzai^C^zZ*-K6c*(l)oQj!Qb^>fZ(>quId|5cofd- zgVR8mG4*b$B|*xpW4w8r0T>^O*_y6dA#hUvG{QGHtvB20iClbq`IA2H;Z-p*D{VX@ zlZYiz2!>LmvN*_HNE&PRTJk+hyyEz;Vo?0d^&!F^!xRn;jh2pglDj4s&T1JRj0@=UVShlxIdY@a zLD`VldBn((SLD)1?D$?1i!f=1SLlyuo;`TuwvBv?qF*Z>c=G$q2Q3B-$Zi^@$>=lr z0dZOenXz-Wv@sU*wA5PAyh*ysO#PGQ$;?Pzk_yTY>ji{LKKBL54?~g~DAx_3h=V=B zBa$c94pikGoZOs1(N^f=^^w_tx61ewH^Nr<6`Y0bZWGdxHNrU%X!e7FbqmSMw!6nY zsMlZ@A$7SCu(NmJSLtxz{b!~W4v>+)j=*B~cDHvfbl{2PQms}6LYK`Q&jqdRl11*9 zFkZf_OF2r?aS9lTP<_H&X*quG6ivuX+3rY?l0@c>W$HNPs2!@(3g8t1wWfh0nC8_W z5r>POtUuie({EP?o?a4dwB@#b#dZqC{q z$?NZB`Y*1;1AFpz^q&D9BW%TJmF*Mdw1*wJlI+CS@C=B(lL2K<(%k&3Dm&wY+4oL~ zrxm`BKUQISFY0{5vi#ix4r-z>M3eWSr%m*dGR1g^)W}By?7gBWT|kzk*>1VTP!Sp7 zGgqengrymmCfL-uh!m3=;e6aRbkWaPYT967-!1v;P=a846nd(z1tmcP;Be{*hk=wU z#Srep+TTiqivXbpcyesZTR9%IeAsCd_eU|DL_PR)YH7;^Vf=GkfAQ?iWf)TNv)j2b z|CHM8g|{dgJI$vj711St(?g(i;N7b&eD%KPrHbokcjE=sWyxo`&3nG9eJ4Pd$3vQ{ zzeRq#Fw6{ps-X<*@*Cp2`ezT%nR?#Rt+)9&X7OEdyRYAU+frhsLE!C8<1fC*P|KSz z$=1Y|j{xI7ZIFeFxfp;CHUbuw#ijd^8#h+xBc?+wL%6WfENtCE=Gt|f zeza-TKpd-^VOehIW~QIrcn>3xQ7D=8@#>r0l|@1Fhqt^V;^`8|MjxR`noI7AhF*$>|nSc zD5ux(*(?JjW8{Syk8Fi96?NV#1UYt$h3udISrDUH10C8~?rJeO);bmkp+~8k6ho8q zpW2UWtfoz>r5#_p5JD=vAcT?nSDo-Tch4Vt;O`aXAEEBw+w5OEJK<_2|6}Fs`>wna zicO(2Uw=)i*h3tH;w~6SM@Wb51Pnl_yZ1*=G!z0mj#^nwA4W#-$3FSv6?K#*=T^Bf z`?Ys|c54D63F|avc4vr_H2a)4uT;8Rwt3HP*zn)R4JFNM>fR6A4_3K?mANLICUfJO zIO%XN4LOt$i@V=x7TJ;2e)E(8|raT~3Eh^{El0}%IY@BRkrDu%Gkh2)CIO-i(h4rfgm;1JVqC4q>`&+uF1?ft>a zZ&aTQ1+vQcF{-GZOw!@zsENeYh10k$@QI158QhqY7XgY!0_~ZK`>Z~HnjZDQ=Y<_x zVA3;Cav1(Nfh(^zWXwAZeeRU13Uj1=JpbV!j`>WjA~%B4yBD}C5<7v1JGadr2px&e z30Ikd4m&8mPW$6pC(m!cmhv%dt&zfEI@ z>S(hy|M^IiLx9<31#%Wc);ZGHKQ$(T@C<6mUDwn{8%ba3%>ATvvwho%-Jbvhv8IFV zqq|5Yh=^Qh^F_k4u!;V|(X`BBj%(n|-W7)bFw!#(e~3!!x!UH9^mJr#8;d7==QU2n z7ilvzcn@mdLd9niQHz88`y1l;#lfn)#IpC`qYFpa&b*kZBISd4ZiGYIL15>9D@C&l zE+d?pA@HE{B-=lrIxMTo3aA9k{3~xoB)FbbGgqbrAbEmZuX1{#lD7dIz>&b_hboYO z-Y*knSuvf#w-KPth!Q}Rln#`DzOdhcfbhI9bHD?qGe@L}(`)^(UlS%zNjGyYah)*I zC5pe&VX~&L;+sv5;~B25Jrgj=EpjY?P}ZEaeDp1f(>*L=eDq90qL3zC3?;F=esvH< zj3+CTW$#X{Q+kO?{F5Ed(gVfV)uL20id4}EcF!<;{lY}$QIg&3?}?3^tV|;GUZer8 zdW#GdvNz+t){JAzkdwoK#3h`5?$esZ7+N;HV*L{Y);K=>N|&M;LYqH#YRjWY^p?~t zezQHsT0#C`Vp1K%J=5}9m*5zoNzmj>w7S{!D{zGV}vNLIccNb6_`IFd<^u34y&50*^ zNBt@;cRVM$?ZpOCw6+d>V&?1l`Bhx)s3y+r#fDJ$wrYQ5X6Wto3%Jyg8U6tqaHC^{ zNZP${i9*?`J-~dV*X|qO)-g}C+r8jON#0tGoOpmP*b(rYHknbvI`Cs#{x6E5$dwQH zD4;3-dUyN-cl19)DSSJ*&%i zmo;UOtsFI;L~h8v=yvwQCi&S1L*Wy}hum%l2_hZD8P|S#O*<-x%=Rbkrbp(e0sWX+ z9uAw4?tSN-E^yC)9`%sUnAj@=m5nY=h}FWS0H#P;VlhA3yFq4`u_l;Q=qhAV5yA^| zBgagLzA}ti%MM~c+Z1{RCI&K3O~P&Bi! z42S;gPCdY7?CK0GP3@g+YvHKLT7|*F5(Wd7-^FL$1328#5uvg~T5q}8o-?9@F%t_# ztt0-V<%NnZMD(#M3CwOM4I&zazs(%=n?6jue-cO>WNIBv)7V(iR@GoW_qi-ZS#R}0 zJdV=M63!Yz9j!Ott`CHDr&z!Tt~3StbVGzqjQ4MRn|sliN5Gg2{uC}^0Y~kaj6$2V z3l)T@SKVR|=+n=AcBGldnDN3c8EXOW(40Vt#q3Cjda;n)UFtDs&L>!UbYWAs>gOr& zH^=ucepz2goA+1NF2zfnTa%ieOfiH#|6~`l_V|i)L>31J!nhyYcr-UsyAsYCG5}(D zR{nwK?N9yqH#G3CvUq>MwtoeK0glX7>+N5VVgE(}|3;{2;qHdf49BM~bePgjjkOG~ zU6(q?>fVPwq!T}>Z_nR!0L6TJ;4ygI)$4)lfl^88E6x1yCmLy(WAWS2p^As1>~h}E zW83Jo%T2TPZsk952r7p>vnj>LFthjO-5o2ppvM8r zepvH?5nX`U1gF$+I+^T`MMpl@Y`rG4u8H?5?R6G3RZi+Odmrni(zr3_YrW{|Pd~DM z+xV>&5|otGKE1H1k_UH70M5Zl&u{o`lGWX}hWLguUnkrM^y0Wrzn+F5OE_7j{bwei z##+n~1|i? zFwpCR##d=ibSl@XnC-L2Lbyng==Bd38Vt(@S-o^YLPyG#10p0HU(db*h3Rl7hrJiU z1g3kdn-1xsHTmKk|@{hspA5}eoMnEGgm{Ad=99~9+tx@^)Y-J%flgN>12{ZN|6{(Ao zP3AZGY+O3dzLIslbbPICk{=W4t-VNx+o~eptd>2Gz1y|HseHZk@l{xshxQRFoN9-Q zb0G(xTk#WH%Dt;_!>=WIXUdL9mKv3^*kUjO*o%mV8M)l@Pe47f!Cs)o!_wV>@wg_e z5oZ|$1V$ie&X}xD%*64hBDzfe998m#qYPTqZ6F83So<7yE}y}BZ7@e*=#Vfe zEzgRti}q4KYux{j_PtQqV_75HoGakg0DwS`~GAI`!G{G zwOdr9NN%z}NW3(@eLj$W^-X)*vQq6!mnT~F?f$MD|IYto{M&ycY5hm$&BGDMfdBir z_=_|G#9NLzJ(WQm0rr+pffKv#15uHwdE@?C!GURvgvar>dKK`^cN>nSfpplON{*IW z0b$qvq=}j`mtmRq4o<^J*7B(d(f0koF62lR`vR~;Pr)9-za*j$#{qe_Bz<0aAo>E@ z3n9&IN=P<#B19h+pBItQDDv%wPy<4ZwN%FI+JiKyG>HA`$A#`>owLKtcgmUZJ()yn ztUldy&vbDl8vkr!;j21qm##wT`^$&BHX<>+ax?*p4xmhhM0q0oTY%0Vy>iYWfwTiGm|z93fhvamH_5-qKB=~miHQb1tM z7dO&-8!o}pLE?OkEya7N)CNeQ^&hp=%i%uhER`cjnVUQ`XzkbafwqFF4MHfV@e~OV zIrr}9?`@jrO+1q3%_W}*i20pAOs);%S?ePZ-r>8_JVapXe_(nv|#0H$TlNcbJtBvN*@ z>>Tp8$NQzTT4F<#RtcE&WI+fkHw+UqzL)Vz8?V5UWd^szWxQUX7#z$`?tM68vy{w1 z<+D`b2p|f$@qZk`^tFWldd+`pALU)w-d-i&TDm z>P7slv?Y$}{arkW>*(H!lNl6F7`uLhaV@jh^$rFBNCJp3VVWzK!KraVH0MCP5bD8l z+xUU;{HF0DuJinyg*z{KNsKw$c@>^SY61_i81xwh?PP{!9z@4(pI}|&{&<*0=(Cwo ztGf@eUoYQgCLO~?28!64;a_!m+C>#vQW!1*YGoPlM(=|rA;R8KE#Dj<9!T@7^zS$S zxTD|Y@}fp|<2KOWqt5*HVlJym$||zD_LX?_x7!VZB7)|92<} zJBBjwG)ZvYuqA0ZibGf-cM(Qb#LAH}g5Z?H@MG>RPlrtv)*|K|V0c`8hY^i^`^Mfj z#cTk8n*u>e_|*?Sl(Q^CRD&qd5%5)+^O5*|P?)S}qL$z3kZ!qvvVB!~b&n%k#w@sMSQX2S` z?N*H9W_oW;Vp31=FM8*oQj$d!tJvdx70L5k#Pl4Zs_Fjb*c#bd2t)j}`u^s||Hr81 zcc9!1SknGY9sEO0D)0Q2ZTTNv)Ba9V|H8Q_YJyV-OP8O}fb0o1CD9B{-`eu0L)_h! z@p&kKbpA1_KGdabh@&}(^gt#?Y;sguWAIcjewGK)ABvGlmQ^e#23u+hB|Hait zBKizREgVvNPwAGA|K6z)qs^J{XJ^|KEi=$Q3E-NO)Mu8@E!yGa4%-S2Usz$`&{YS}KIBpQww+uy% zzi6>V-(RhZ5lMmUqQl+ymhLpfGS=htsLE7RURzd?#;iq1 z)`g7Oi#7T4B?k^1k>G0@W4E9(t_QxhJU>%A9TLYOfXpQ}idn9HTHp*Zm{k1taWen{ zk`vC}9pMAybwiTNP$N|#qN#wm?h2x3C3Fs4c zV-bLMR6Osw*Z$+d;21m2cwon+o=NEN{AC%yLlB_BOEg#ET+mK|(hm>Z3tWt};7CBy zOr3Z3e9Xr7Ux+~kH_&8MN)#p83*DdXf#kT;cm_X=;N9TMKe3Q`6>Z8|P^)QF%A^UC zR5UzSu5<_hw!8gE_=hs6;{`WqvE|GDYutLSL#M|XnyqXA{(@y1iHSr2m>Kp5{-Xe2ffDkb}WQpa9{5Q8SPyY7e>M} z^Wtf`rIz(L14%u2C`w`vJ?ebemlS2Z+8wXv39DgKDToI&6iN&|z9m^@51e1rl+cE&ZM){mWSy^rG#U4W`N>zS>)l0u> z^xh;EgR+Nkz1&uNHmpW0d2=*ZO+gAy3655K)1z8m@tViX>sKqUYY_&e5kIX5W)az( z3Yw?%iG;Y3q!P=alH(h9{4RF`4^}w;rimNK5m?Zyw|oQhoms12+J6J$-Y?X`Z${sU z|7GEYek5iR4Ej2}2Y8-GTZrQT6EllA3T$LTzqPC>|(`F}DA5m@c|ufWlNUkUncIPR#754gHD+pKG3o9VWW1rloyRYUrt z-^+(?_0xyXHD@=?*f8E6R9ZZe#7oiChg;oDcnvWU^jr{;)y&{OFJ1)bGlQ^cAPbRo zeEnXwBcwFGg&T;%h(rsJuH(H7@q%kS?-<7jERv?wP;#Up?nEZ(bm&1DC>;_o#8^@)#29O`WErAOmXM0FMH-ByvS&%wFf$|#ZCdQRL5i$Xk!{SN zu{6xsci)%mT<6sFxz6XD>zv=Y&iD8Iqd)4C`rPz-zvuaSJRgtyNGwJz&$pR7d5|YdA-w)>)QQw)nN{1LkC7 z#zfmwYHtKiH~2#_y(s-p%x!;{f%+xb{pP9rH4OhM?)dFL|NOIpneD{Y-$e%gd^q|| z9s-hN4$;!EeY|L|uAHVP8Ir^d&3bdQ3&NMF92>v_2XpGF#wT1@Jx1mXI5D=}muPgv zP>qm0U7%iW&o}5Zfh2Glr8kUK1;w59&Wt?;r^wy2G|1)3p3Mi}X-S(DAEjopD3S|V zHn!WOCZgH)Lv%yhu$9O}WB*SP)N_NuL(PwbGcyjqW<;lSnIEG-I<0TJ>_DCeVz{Bg zcRu8SmoWG#RCkX{k-*Y5hNjP$CO5ooIc!7|+Mcou9L2oBCHoqRzXB8&w(1%9QF9?- z%AusKUqO~(^Gv4(G46xF%9~`={IP%ay&JnRmE!q|t7k)mG>;p>7N?CA^JJ zNV{*nR>qbuk^>yCO!**Mt44u7;ABHT`c&a;_)`fJ&=^mgFr@U)_zvL_EL_>ihFabN zNqW|e1-7g&-pm-1YBzmvZX2%6n_sdc@&s@~Oh8aq$;EAsFZw*wt{KUiKu#m>tj+~q zMact}zs`ZrQ>@p)w^Jak#Rz6*?+}56m#bw%d^F^g$+xYCA;PE_snmnRLOQUZQLOoFyh~@8_dZdc z=H1k-4>Lgog4I4cBsX(!!or88xdHR(td-z=%{@*XXT026`zy=Zw1uz_vAI})?D_w6 zhPRcBzdPuEImy2%-~SPb_P=|E&FUxY4A;-?yl!ovOj94>PnGDs_FgR#`cSUs@KiLi zpbdYr=Or{JdJdfDzDrYdcR%mPmd1vN1E*jHre}Da29AhFE+_Xi9XrT}lQ)8^G(dYI z%iIToziY9|GUt{FT(J>Kgf!n|=4O8G`z4756d$dp)1Q_O03$oFP7*C$;$fho;WQ^d zS;~4i+V0@k?bc3+qxJ6LPh@Bsr`O3VF?JZBa(dokxH~pX`QerpyL3*4 z^_A`a@|{e2`(8XG(3p>F*|#rI<5Z|5&{MdY%Cosn(?pr&+u6c~bb0=3oV!v(@)`lyUjW6o2dHlcVmB=H&^k`xxHbPZbbYPz}Ot69gD zo6kETpQ2z*_;7V>jZy>gw8#4gJ{n_`Ifc2>?~0E{jJsTg5jjG!qL;77809(_pKaz> zb5)p0NyrR|I1wBozQTGXV5D--)0z{J3ws9}JvIkJ_~PG=QcJZ<)g_!dVum4OG`osH zZFcNKdxdyOg$}D5WY?pAw+8%^H~1fif?rAS-+Xj`l-2Eds>klsEd0}ON;y*T%daM) zq(T&eA4(mQ25;hn)gd@#e>GDX zlkO9FzR0gMNUG9yV{t#=JJ_v%hG&wC@@V*?iL1-3-q)Dw|6g19~3 zTcIA&P;Cn$hKQD7eVvLaivK9Ir1|J_u$l+_186|ncM%+WAv%PF!Y^Mj)ETq1V9WNi z*M7!%DoTF;Stj{IZGMUXe%sQWi7uryKPp*2wPx#uaO-C;FOO6mziCs~ER$An>W+!_XsuQ%{u+N;TRpN0E z-{0{#7`3z_2p2?Gc-GL&$osF8Q{ zS1t{p*q_})s=yuh4QLs9fgyxNxwzvJaN-Dbmt!PB?5$B+FL9Vx%9IaRX7@k`wOg4m zg}91%Eq&& zp<2eD&S^G{o~z`#tH%YRfzowWQ3--zsraeNGzKhXVtsFo7jYtQ!~1}N=)J@83fu6D zAMGtY0^?y*u~UNtXuYg`VEGU__C|}PNf`bDc4p$+Wc8#aa(%<=i+};|tG-n+V$A`T z2C<_f0rf|>tet%GJVsrUj;am3XbQ6iN1RCfm-7_Ro<^zw)7hlS4Q$3aO|kCsO`=Bthw}8wXpy8wz~Jn&xF4lx&JT`y)kZxR0iLv>|2aW zlZ(basuNK#YwS$s0r>_2t#rFvKWmPL5~U?D4B$LPRSpWm4x%LweWfRdawbUa_paP& z-73S`yvl_+wwGKMW8gxPcB~Ys?=GjSp>So2bUD0_R=IKWf`4T&bKWh!G++)!5TaY( zXwfoL(eB?%2PR(m#Y*Aky$K1zI#K%t5#Vxv=8lW6UP4G$0?LgH@yg{KwUA{w1MWyk zCt<7ypOXRNG0X*ByN;y=7We8u1T731@#ui@il#&t&NuqjF;cCPvw1hfsJ#Fw>i)c+ zmT{wF%BJ25dtJ1{Uo@l@`%|Lt+KVuA5r%8X1LQ89Pn`M3_@C?L@3b`GeV#V-1kWVM z=T_RpXTkU6mJWWYYO0jtr;~qY=B@W;sbaF_#?NMw7H0Ofn3NHCVJ88VWOL~zadxJk zgS64!9SOGo@4vl-ZpE#2K4-NkqX8;5_@e~1j5$2)l(^_1Mvh675vrxGhhL)oh;Fo6 zXRlQAM%AQ%OPi(K6KD$vvQSh9cAGqbmQYJt>5w)lfH3xc4U0$F=-}CIx;=km{McEV4uK zJx*Va<#%7AOX@x5vzU|3-yXb6iQ@J!kEQ858wTI)OZ{gO(>pwpI4#p(ijoGR%b)ax za7fi%d%3;efy4vY5pHCf@0m4w_LmyF>38R9B50!#_A~f8$8;o3o*j&2Dbqkz~y`4uLNp zRZ%nBFj8(EZ#7}@0rJaII-_;QBYrWb#?;*31%0~N>>TD(J=MSU4t@twtGa%t{r{#B z@YkZ}m-+SI6qdh6(Em8Q|MfNiVa6;o$4b0YGxl7kr}Tha9)aUn6YLo%yUhXo7&$M- z(KUhVger4cP5TsFp*;Ac3j(CGC-X7b64W!?80l@VZt;KP!%M1#2YpA! z3cu<0o_(vAHB~?WJhC`ye@*+PIWWTZK4lUV50M7c8Pk-Fh5*q2bxlHiMDfl7%}*ts zN%u`-6n=8wH%a>|b-az&E4PkIn6`EVUk{+a<4F_eYTNGfWn#MtR0TDPoIc74!PjkkE3n}F13W`b~B)>a-#4YRBGk?K9(p`hI zI_2U6z%bR)qh-GZmh<%F!dmmu>0wA)ZSCsPQ#DRsr$!iyfJY_Kvx>-Pkw*)uMEFTP z5t5O1xMxwNSa>t36s9j{E{MLxl(IvO8GvxsPyBG7TlCJPdt&uchMuI!C>YMw-etpG zSU$nHZzv7gSr^7Dh~N3L`L~Hlye&>&m@k=yp!&ZoFeirzSTqqj$_uuWV;6yGEk(ZdyE9Pl}O$pvNi?Z{1{DBi5YvctHZ zQ*NjFO}7R=7m~{u?WX@e&B#s+X)_IME$d;e>ZRjF{HWDW$6;okVQ(7eB(#Ih2tJf^ z_nEapP5wFU|6k75ugzpH^gmwk{F*NQr+4j#;MG$nh>?Zs2VQPmF5a1Kb2GyPnmBTs z>C1{lZ_w%&!^MolE8|)&VNjxH>Dtfcb7y@t`LMpemiI9CpB)L0GUq}@^&ZbP(-R&{ zZ9d4`)Me~ndjVyNrg$@3uVTNJ=TwOSi%`PR22g@R_V(Wb>FC-IxcmJ_n(%K-3-Pq& z_rRy`6M+W=Q?lF$l$onT5cE+x91lKNm(KijztQ++N3fC;aR+XV?z=_hhim$NH+&X( zcjhg zw$G@VFc@(M$+qfSS$m_5lQsC-g)0o>*Z%i%MX-`ua)@xMi@DrS*m#(vV=Va3^mW*DBxSs1BEk_f(};`V$*5=Noj=GA zYB`_Pm#xRMfuaMqEyXK!u%U=M!6@V~@m>3;;?mKL{RCq9ajkHrPinw_rMXcCK+j)y z(*>{!2+-`C1r(u#U>m9aCsl(j2EcPBlHgZ?b{T%Eenqe2M90WS*pM4c3M=GM+`9b? zG=ku6j%VrP(_O^hfy<5!v3?f{hP4-yNdEFgQI!$um0BmR3`irgY3VJ+`lP`e;ywGjq_9w z)%NlZ3k^<>`4stT`L4pthOIHG5o}lKkmILImhC}X(?pnd)%h?yGExAe%p_o-2`0f4 z6k}Z&h4_i%Y(H;Mlv>p*MS`h;aMKgtDrNX{7R+%X|CIj=F$>5VOJg73MTL6UlkS}s zd&$Y|M_8;-pWUzKw-i$69#EsM%tM1;-x@k_^TAZCyA&dPgnab!q{v;o3&5YMJqo>o z-C6m8hvj3Sr2RnP1c#n5=1MXYB-gCCNY|H85di-J@d63!+;|(N?Hu`hH$TeBRV)AM z+MC9=w~P1#8_yMszXI^@!T%?XJZKRBWzGwW`488Q(PG(ZEo(-8;r= z$c_aKvnz-WVwFQ99?gA_1<_Pu)OsqEl7&33cXn?$YxX&Au$fU?b!ASz#bt3VEF?4a z?%D4iRN-v53pOEem0ak%%S|g!1aPypcLBP1*;-0~Kh$Z3WQyUA;mxyqs6kD<{Q~mo zNXSG;LehgB*!fgIU$1SE!nS+_lL@fBW$|vTebM8c@q#rUO)F{~Jxu?S*g$lX>0ES3ar4W2PQDsmBQHwe}n`}$( z8J)=SclX|q-i^3Ur*pwuCBwdZ4J-!1C;Z&ecBKi_?^y{$9?b%g22Jj_!Qnq1?z224 zfqs{jpcPNe2*K8FZg4+4fz>RZzk>`p9RH(%6e!Z<>m=OP*cBWmjX38k`FZxXN3Imx zU8HuvWEemQ{CUj@=u)D1KlLdnQrRL2)Xel0oG2~i{`Jgy9Q1l64lMd?tHHo+v)*=G}d17Me8#;r@Z zC;WONT~Et6wX&{x4Cu*YGYp`On5~f{hU{R$0xI6T`CMcG9-$5pls&2 z=tQ!ChGtY0GL3H=Alh7;-c`V4zAcY8f<`SqGJbM$C6i`Ax0X5JS<>WOv!@HvF}OCO z-W98TAL}#GQZdpHa^vg5t{zpbjvnp$r1lNv1hoA1r(Ven*?1t&BoBk4q(g7Tn+e{M z0zZNTv2S*5s>TNnzanBo@w|ZlC#N&!kCW7U8*53sE_;GSzK!iHDfm2-8^G(dbN0mM z=JD&egt?U*;Viadkv@bBx{jGRw7%x|F(hM1kaAQoo6Gt!q?L!0D#CY~$xT?VZSPkd zfl#dk5osMqt^BzLf4lvdIeILzIoPXuVy!f*+^bS-wKecaday4koG(kQnTY5Cas5!( zhKz=}>TXjvvT+yC(zAi_8CE^mPO%bRI4JQPI2#s#i4+DI+*-V^-w^y!!j>(Rs8e;*?HB`^h8)Nzf$TM7uSB>~OhQHBDM`iz_&QFc6fV2-zW=vJ5w1 zo4x(hp%XF@Ob*%%yx^p4t@jFw-`7yP=YO>s<|TOQe%J1QJxISjeg8J@|K=O(FC=c> zw?R?1$hfY8jr}QUj&@n30_BrXY}%#iS$G(aEp9(zOdzv+-TZbazC%3iN1)_SULX07 zuDl!xfT>_<0KvV%?%#nrAj6!fwnt!b$Ebe#r~d1`5;G86ihHPN%9!ERJmU}1mlP4j z)K_Gc&6^cL-wi-sJLym~viC57=z1KHgW9D>Qd6i01@m$vky=9g%Rj|ce3GUcNnxhf zK1WI-)X^E9#oVV*tK&OQ_&4%eg}$RFNg*5?p^l$&lD4TMT$t`Dkb_k<)JVBKE0QYu zHf8t_=Eb7#4vXH!Ax}|N%;FbqvmQ0uOZI{Gb6i;8FIMciLTgcm-oeje&3EJId;5pg zmNhAAtS?sjIjBKM$d=5{w=16dK;cBXu!6kuV*D|#=VFlJ^~K7?ON{k{qnz}{p!t$& zm+QA%?oXNG5dvJT4ZAlJj!K>%Q1w+R5qt^84Q98Rjoo|mwp81tvadz~h$p9oP!6Fs zg*D%0*>{Dzwu}iG;!O%CCQR3Qt-e?zy89_297mJ1I8>RREW6)Hzg~3;w*L{~3<0zs z^CMi)XSPY<;?z(JMuX4ta1|30-UpUI%#Y@eHdMIPR$)Q@4b!P0jD1KTcCTRiqRjIz zo*yposT3O-Fj5>B(C@ze4maK5KC-AjeP1;7kjWAe6&#>-wymZj2txgkr{LLxC2ns& zo1UrO?D>LyU}B)f3``dyjDr3A%yN4Scl=-~a+!Y5Yp~Pl;;`ISDKyEMDF?`W|FWt4 z{rvsf*l)9Iwol_9IjFzp`G4Hc^*`rH?Axy301S~Wp4v60uOE2K6?OPBly3&MulcWZo*%|(!f6EUlAC!zZ3G0HYhvfZo%u6( zYy5ct!CyRbPJ!xbaE%#9w~s+Gs$Tfu8dP`VT1v>*>N_TRxyUM2M@aYA@QIdfw#Y*) zQ98-7jpY!!Ko`&!S=X6tndFt8%hX$mFp`HS8uHjs6^MGPph`RTtcNULP6KS~<*f8C zAVdd6co!w@6AmBoPPRe>+f)1>AW^T?N^SUGuH6YI)?{qZ^}G- zRn43>`-z`;Y83rW@0QBiy=zT0ptCS#$(3|6=ed~N_7@rGoYkofwOBw~*r@Q!lOhbm z&Y<+NqSguYGBH|MqInqb<3ES(MM{CtUqP%bzt=k#<<&y+NhKDzw*d4;Y2i|)#K;ac zE!pO-1Kjkds4Hh~x&?}>^sD<4Mk!q2goAx*ib5Ui3DoUdoB=}d!JDV)Up$B(Xv%Ea zE>akZ(G%M>o8qn01TA;RAZC1s4ozLL&gvtx)x>Jn%S)l)Buf=jJ535h*mG3@_zJECnA{+et4y*KOcIkjJ34QM=t z|D?RJ2W4w)Wk~&~NX#sOI7uQVI zjZ{1N=0F|O^<@!qfnMHmo(CO}<7^&p%px9hVF^Au{O!3-_{nnMPgxP5l>eAh%ueo5 zG_YvNn@gk3X`y0iM87$j|JeG;i3_N>=En)%E@}p>C0@ILE8syc&ZBJjqg!JV#gGk& zGp74Gcs5#j?D~OXL5%g&Y|v*K<#?ZVCM!$<@_&+zuTxf!F*&;bY*{ktNNNw`_Mt?q zvpSWIVnvQG7K$rl7Dqc2v!PVt85AYUrs~IBmCd%&(PxQ7?;5x6*z+|K=1WXFXV_b{ zI2%OFLLP_>mCwxvQByukwCy%?SmT91E;TOLrY?t5zg817Uk7)o_1j7kNA>%5Z+K?5 z@7xN`xzDrwbz*qOR)eom{>?q{uV!+Wt(m`=Z}iWI>Ye2+zQ<=dk;woZHrF)E+I<)A zPnqut^XXYuMD2-a<}jzMUI6L!KxUH{#1qCqO+5ckEaE{PiG8z%wauy?gInxgq}K zv^kCmlRXIsdY_W_GVb33<9jUX%uRV0Q=4;Z0V;jQopQl1>>^+qZ&CM=f@-eppqdKE zmk&?omT;Pzd1wfg^3g9V?o^kxM6Gg+Kug_IMM}RmN7X$|P?>I^_}gFNICSQMJYQB6 z@}32EZ*oImV{@;})0yf=^Q$9E@wHRZO(u6H(I z#D(X_vsEzS`{q%27`x{8i2_~Zoq(&I?=jeY^Jx4Y_Uhh=Jl!Ka0eQq1_wA?V13;A2 z_#eCh{LA1{xgG!i6L$gFC&|IZR$tFAP#{=BWFDP4S|WW}?eNKUUO{c6F&>Nc+9gIw zB|tJMagkFixwVT7g=xTd!2lgtAMheM{O~4_Lti_!&P;j3DbJJ@rFcMh?@OyM1r~CV zG_?R(!mbj&tTSj9Njq;n7Ma*vr#l;Gfd!m;Y5GSZ^5ZbHLlZZ$^EB|+;(Q!y-_h2O z=e{3$Z}MHDwTOh?8UK^eu^LDBaRt;yNYkZiCLz&ZX!v)!**IJdhSPp|E5JBA4o?^2K4u)XH(E_!s?! z@ayo6Pq-I4`C>HR_e0w~c_X&i6qvk3o>7uWXf^_4KICB(r~UG! z`YUUJ9*li+G(TZn)EPG1F<_dy%`9J9!Ng~9O!@-L!Lw`5q&L=HaIb|za}II(i@Crb zv=OaYt$=mm((Ziu_+YT^ZG=TyDBR5#%4tV?VfZ^I*1e_`;W<9yHb9yuSP}4ZBmB?@ zd(iT|$qyk3Yf{+td|3DsR&!wtU?&kG9X>2@qrzD+E&3zm3u6tcz%U40h(?aC)+(h* z*;b;or=@+5As^DnR&18+pe#2GA2OehUq@ZsjrD5HU`cS|z5D5aIk&~vqp6MVX5mN7K1&62D(&4>q%I8G-!8LJ8G%j+o63&p0+|KL|dw^KnxOosoJ+ODZY-(DIDyg?O94J$BF`BQ4XFX zj?g?Z+$fLYH?jcu383h=C#La@t==>ojw_AGdK*`ZqE&LCRj(w zBz-ZqCVu_5VHRvp{RS_?Pi8}yL5nf~WWDM`Z!epWA?W7vF~3SqA+a4ysm>|=uVuNkM@In|$E^PDN<=;o8lb#cy$1mYNQ1+~m6{K#vN zIhT`kA0KOOhpu=R0kb<_2XO&~O^{{!RYT3UeDDKoFaxG&FXAxg0aHgWqeGTNNnxklp^*+@U@vC^k~(Z? zvB~q?$o0nn(ruBGi+vvbAsU&M$AnBch01{KO^A{z?aR5QPCc_jxA7SlMic=W>aSxj zAjp7_%EmDksx@7nl6i#NMXz3!tpz!jXDl^>?4qj?!m5l)I(V_j>_sbsI zX!Hr!4+r0eM2-8_ZPp?ZswmfA*cS6JjG0dJ#V~<79GF5+q6Pebziz?$%nxBQsk0NVqnfaA!Mliwz8u&7xN?0Oyr>)!D>@RV;G8^%bX5HMqMrv zz_MoasZE0NV7+rYkQ3*seLt_9^lOhpy(=ZjDMP@O59?b54WzXexIJOSn&#W}oP-&m zRwLsBMBI4>EV3<8Zr)d#WDl;DiLxIEe5o5So!hdeJi~U-Cc<0_P1%&rhH@n=T$^GW zcu>mGQY=viC4?v(hktF`Qv9f8yGH_ln^uF4m%h7qD+u)D;{IF#|A(cJe^p9~df?Ki zfHB3S8`Zi~Jbl^3i2JIOMT~4SxI6s%d-F`5z9+=g`z4b_3)${)ca7_n=KVZ`tr?mTv|ZHHAaT?~@&K=%6NEiu zOt^IOLoHG6L(^ga9z@Cw7^Ku(i*WCZUaEN|KQw)wrZGcYdsh9`pViu?gjXdYigJR2 z@!Nu*#Z%k4slKD+tpZ=`pFPeq?HGxYuEXQ=hNUpn>c~!{ZK^+RT3tIH#iDiAh)&sGYP60#3v1VJIE2l~KVB2X5!@$Pqq*e|Zuc3yb4pGntzFHtg z2FPxZYc6k_R!IdG-=wGG^H<3bDkmtCekyF#O^5pwO6@n~R@UL=ICwoTH}PS=L*Vh| zNw%_RYP$>GWu}@5nO_esqgL6U1mj<5dx9Q38M=UH4tEHZ?cpsh0~@qvJd*$5nZS~ICkLTa%GpO9z0yF+A;TZ+4{2V{m(22l_24d(3p?V_=2^LX6DJyWewd^ zD~LIDFiAD_AkCP8Y>e+7_XdFPm)J{DGe`TRhqgDU$^WrBo z<7#f%GQSsUn=jGju=LKX5|cUaFvnI$JjzD_-Q%_dfcdtp$a`%&haM!#<`o?#SoOjj z&*|xHZk8PsKSytL{xG6K7Z4vQUR;W+@m?fDu&P^eoXFU{#pgflm*nr$0CB$M3?>14 z4SJ}<+bI=-Rlo64jk_z1bmC6T#Fw>i5XVo=K6qn}n@jyfa^$+rgxz@OmYP`NCDk)A zxw$smXlo{*cC-3|DM!0)d7G zF9NIlA*#!leHhUadWygqi43R|`=P>8#*5|BlIt5CBV?Im)IpV^0dWM)Zyi9(#G4j6 z1fI4%9~b+`9e9GBE0t~)gmzIII(WIY4b``7weIX$Y*uAZ+v&*$nqu#nfSUn=ITMCM zwT;}~(ova|%OM7~j4Q`p$TWPFN6G<&dm7{tBYigTAhVrLs6e>0|4BzpaoH<+y{6+cvdMtbe!MlN5r)v{=fbURU-Omhl|ON4MQ=~?zXqMZck2G> zp7mdc9`MZk`TtcIe#i6+DyrMqcVS-!r`gvEP-6FXS@90P<7Czn&Bj1e8U^6kzFl2` zfawMVjSn)hzAOfeZ>p!#$`E7O=zSMO7W6q;-tgv@9U9j2{X{3w{BMZfH7b?*cv&+6 zKZ9@MRFQblY?46qL$G%{Px?0>JLugGQo{x7>k!=hxyrK7YmT^EZKEO#^z$1Bg66Us zM$WJAz(wuhEWKNN*)pdouayD$cxD*bXSxg$*`;Emv_fT0?SBF#8+*P7xt54LAiIWB zj9_!C+~;xoXL6-*;L;hR{#eO|8!Q#)g16?!^1lb+Sej!CbB5?4Uivz7RSb-h)u zOuXq1{s@v_NXYu2AgV$sE{ak*mNzn221#z2;RTKr0K(deFE^{lx7|h74h<7MKQ9ZU zdfVCJu+Blc&uncwf({Oxp>~20;UZ}!?abO%pn4>_YH_24V)Xn@ujj}E(v!52SN>~9 z8eq)8Hwj;Lg|X$YkS+lBhd;W4QohwQze3#tGVDEk?e&_k@$|4RGdAqgTK{D$wk$3< zXiDKUb!oJ+O|u6~GMpDegCd7k`Vl!Qg4N>-t3fpJ88G2EH5^{O#orT8c5H6)Oh4JX zdz)Jy=l9&;Z1}k_bEBb5y1r?Qu#uC(;9*G)N0|{*Znc*j1`4lzvV>C4Wr#Om?f@E0 z@CUWYf=H9F{1hQWV>wloa38?J;5-fF3dhXzHN1vp)eMRpQS*pmGk%s7+DPjTf%$K| zS2@(y%r$n~Mj!v9_Iokin)=K0^#?@Uf6J8)i~_U&9HW3+v_!;@ErnX_Mhty%iqPsa zY*iyT^AUYR{7fw2{JI1E?qH@RvOM8nC}@V{1A8)B)@gkKeXr=!bWAFlJsWBXtKZG| zaLT1gRUfk)Ec`O++}PfgUJ(+H<36l|dWV-O))SqjkS!2w4nqFY z;75K@aLv^V+FR&3|A~bVv9ierlVVfdWlCz68aPP?^xAXUhU1GD5+-wPX&bEUc)!mO^Oyt{75^rCFIV zEl-EoS183l7TOcu?(Sz!3pKr_x!FOXJ?dfJt$yp(N`#)?dAL?cq`z{~aQ9B+!j0v@ z*(L6LQ(&+J!MbdkoUGP&TVuTIb1I_3km8oYtPk+M890u zY6S2C3dr=&$j<2rhW42=gVyY??cCC!c7)VxosqSE&ui0t&kwDw0qsHq1Smt17`y|j ze3bhDI`tEquaj$|mF6CBlYUUz-zIVO_9!$*ZhGJ98mI-H?$4RA6;9pNw?ErTIDCGL zRh3oj5X1IH4n7DI!~=oLX`Rh|Oi(|XB|$EzdOdz{=0$?Z?B-2rkh`zBvM=IOv(&Bi zjtG2x@a`lhoqeS>(aqk}pIq7_U&)>%mTv85hqdf9f{s_g-h(bh^PM5BSYDC z$-M`vNQ;Yx94b^7%`o`NwxsfBBG+Lrf?hFskLxYPyXY zczMn6N+^L-mH^#>Ap0GO4S+9gRJQqOf+i)C<@v`6v`fR$}9dl>Hri+tk{o>B9j{AN}bR5N9^Uso!Ji7jK{TTw?Dxn+QbC2Hm z2HW3A(|bVOlgjXiABnxZa+TBTu15_$Us;b`_MMW5q0+&IBo;OX#A0MPdjAeDJy#Dr z!`*K@ukf003!ODgPe&So%zey%h#4!852|+ei31}G2=4PZY$ke$u2|naV~{s{{6vcT ztREkiQ0!jl9gZf8Od*hr3@TXkGpEzt!_M2k3)DRcl)nHF_VWNfU-{-QiDoQjf^dku z)8WE3t+kw3O?O4D4Fgf(vxS+SwI^wd7w%9rJs;$ccDj;+LR|Z9Cv7RyDkefs(*+2D zu+R*Wf|%9i7tHzohvn*F$B&lBhuYYIdSK=hhO6T|kwp*0@z0j_4c?xfPh&y4c;F+2 zz%o*u?8=Nut+QgzU%u=20l&4#T3UUjVzMcO&t$ye*mAO`e-fuIsSVJ5dvb-m>G0Iu zsJ{8?#HtyU!u1!zNnG+{Epsof`ch=^Y}egv{B|oIk~>&j$c#D1ip=4IA7#tkvMhcm zkXe7#`!O+Su-tDI$AZj1KIzJg1rfBT`(n^Z3p@nBqP*=KQ&T@`f-L zdvGs)%e?3Rg~7ZrtZcTPlMlU#qT61tMKngUXCzK)FOV8gd919 zV^3?JyeGYhSbtm=p8(x2c5vA`0o{FrpSzu&$hvgDbEVf=( zKA%i$>z(~LX4ovA$`y766_a~^mgcIT%6UXMlL?6o8FTigcrfvpB%wQUvGSqvV4f8) z_mzL6@7wYw*#Pu53OL|EUnX|GL?eqQcv{tztDV9ryFZCZK)iCHmFYA&n&gI;!bPDK z5w5)vxtQ)5C2|g^Tx**HDt%3yy2V=+6_FYH@Ndj_2j?q`A1-gney`VB2>n^!Vn)0vV3kKFr47{`am>L~8pNM=4w z4VGt0$&q-)3YIbuEd7-qwb`@8q*cJP_yt|AW5GHO1-gU{K!yr8YZRjvGof)lWpg%= z`az!V+Ij8m&cjuTZ65b$Z!pq#(TfxVx7ODUNt!VC^Et$`52}TIZ|!|X4SkN2E($eQ z=P>6S*B`wghbX>0pJ2u($DU1ocfQi$BgPYtTknGH=^BrGH#%}+ANdp0mwmM%!3BCU zitC4Gf)}=w#~YP&H^+pdZrwYrV7w%)+Eku3>hHf%&~Z+R|Lr=12)poCqwO|Y=+{=| zKOC_CyE94mKW8SH%nFvJY+*dTUHzvz67JY*$D<{+TyZHZg3_b%x=8I^z_*cyrA~aNVK<4` zf_B$@=S-xJ%?_?}tzTzjd~ zh*x$~9J0 zi4n)3yE!}cygg+1TcLIp=Gv(mrx$h9Y#r8WzHu$Wr)zPDx}`xY>MA^ilGHj{6 z9J8FvBp>&N@(LY;q|xq_(L988yyvZ$W$R&L8&{a+eRY>F_D!!&-X(@Rmj8&jld^*0 z1WwWUhRP0P!b$Ba82YjY)jwd_ibz7tPE6qWu&D_F@}=!Az!gJK^wGhy$i~Pr@yGYM z8qNry_(Cncx<=$Wv)w>iwNW%uGpcZ8uSxd?#Ej`+&}S-Jn#B-Ds~@Ih9wcj1bX|7#Gmf%4iuKv-=RZGIH zPph+M6)8}{Mvn6eU#6h1<@+nfUnRV|D3Lf(u)2>1%nB9i>-}$EUSc2Yn<&vOy;I@b ziNQ>Z_};+>vJdu8)aWkV3Ao&OA0sX@?}ayH*Mwg;!#A^Q4oyVsBK-o~I*Ayp@cd0Y zm0goG5w3g0FTl04^}hYY{A6|yyjmQ9>K^@Nzw~EZ{$Kajf9Ns_q?nCjx}%XN#5h5H z!kx{8U+4MF21?0Pb5CDCo!6sSN~>uF>}!NUN4j?-2)|K?ATLL(11^@QxmYd)#*a>r zJs4_%HuH+=JahNVb~WGhzS8J^MUQ<9xkGm~5G8>j;@2*+;bxtOks`$cG1?Ad8#{S)YDIS% zRZ`W(i||pVv40X<-kl2tbts(=&g1q1R~)BFz&^~kA*aZi+hTC=PiUw~Mo8AY-D&PU z3N;L2h@?yvjRvUj;!iQPjE58BS^^=7H!M7SDw} z=1Wcw#rue7f^xs@)eBk9KJyJL+-_^->{yl8)KE`DIa94i?PMLxNzoMjn{cVBJ!{Jt zPero&Th}GcO?UsQk%(F$vMcZxbAd}}LBwm3>=ySsH$gQU$!6~c09$O6yl9hM$QYz% zs9V=WO`(LS;SQ~UjY zHeYPR%Zv8}l9NdL2Jb8ao$1RvkA4V8h(^W;Y_{3U?SezAET@!aRr%=b;x zqdwK?@qT(+7ATvF__d-!#R8^B^%)-TY7aZFh^Bru7q_n~c=g>wT2bS?{f+9yv*e|F zB!%GSWsSGv2Q@=hd}khP9V0wsITJhH7`c*QD?3UHZEaV^q|uIw;9OVh(ld zrS}AaTM3Mqv8U0o(lF7UOEYR5LQ4$`+O&@t$`m7@(I>N^V+Zhb4cz*Am-xy-(Y4u)qIW^8xuTYwvZho59~r{Q>JW98In7Lc}0L@wfUNeK6g{Ze%%4s_a`KtkRQM&PJgh0WGJ{6&DQQ zz_<|fx*R>jiM;lD_{D2<= zHA2rlYFnkUh3ImuzJNtaE?~RVQJsjNU;graYC_@boQe6lB2vRsU26eT_VGV*T}u|Ad3T*P|g6IXMiuYrkSP(I>4r zZ{Nh|X(oX8p*lHh2h1+B{XhCBRDCsPxNce`QyNPZWhRVdvZ1NVSDy*zU(F{t|J>RP zQq62v1E1>#+IIB%K`0_z6!G>!{P#zz7<a zALiDPDhP6rZzHswdGE8_04|+fbXUf=N@cy9%vdGT*$b2fHS!W{NUF5%YwklXJ!a5C zzwPa8*d&!5B0~*CCKT_`P7Iu#5sXg=H5;G8_1{?iFcx^ekaU{?YN}#-uGWZG$y@;F zQlzzgNn-5_jat9UD}j|8FF3$N9Qw@e&Q|TSSHWv(_(8v|6JTw%%)^HBiv^?5^AoED z)e8V6kjH0nYt8QXR?@x=0cLqgYZf3>f?ptj>f{&;d}K%EP)`#Az33&bW?d(*Y4BOKXquuqW!>vQw-)!Gc_8llc7y6J3n>uXu;DnU5 zh&xfw@+Dhl%4mGj4U$!dgq+ZAvK+pDDQ4yf)xfv=hCQ}*hNFpeV^wTx^iBu1R=6vL zF#$W0CCVtMC~hZM$=~gkR4x8WR}SH0B78g*Y5wsax4!&~Wd5&quRno({r*Yv%k2dW z28@4_!9YeLLTR=D(Y|$FoavP5^I>DGgwSc7uc_Z8iq{MPwT+g{04E>5wWAW)^yp6^ zT7cUHjU8Fk7`Vl8v%mn6L+pMu1(@c$KSzITSh;p=KVP6gTzADzJ%8YOQYR#dhvfW7 zKT9q{@x;*^`)9fX;_KjLvBBNahFZ*Nlb66R_;!=~&(oh$cl~6tVd9b$zhY`>aUfY1 zah3_B=>(oInSC9{51?D^WSyaD9aNsd0_ovoL-+wiGsgk|KSDsIyVJY4A-CocCajk| z(=jG)pXKD!fF(1law)=mH3X+}7vKWEQHLba>kaJ|K zim`Z-*PScaDag$6gg0>MpOH4{gf+_Y-X?HUrQCj4n;GzKWoZwJa$~*n%s4`-3fAwP z7NSWD^V{elwpVUC5Fa}Zrf#i}ke4?6xH?KX5U+RvmwGG_35?A{>oiaiCkAmb)cFJm zy)!m2zy9;*(rTrLp*Bfd;@zYWk%=XMgEu49Y<@X52~cyJ0-Xn!8>tihG=2m#27!>i zLIEKZJ;7&1I!{nfrixvp{FGl3ofQS*EnBAOjv*7{l2*5?WQLg+3z_7!J$h1>l6qRE z(2D1Wv}+^7@$}>6QxO3@uQ`x>4{udy)udYDUsVAm^T}tuU59SVOkr;?Pw=`^fyc7j7^D{}swNiKSdpCtbiw`sBPc_t@U#g}TUcD|)SH4dS zON=P1UbrOpvtDiA5X)xvH zfS*W27{XAYtMNtyS4l#b4R$%C@Sxk@PRheK`vV!@7m zo``G(no$6YT8?tJTwZUOK$cP;#0O4(J7mz@WqM(D<(SuMNiwg3Kx+EO^)7|@PjBWE zC$#DTregeEQ)e4aYn1EK6yn7Ln3;*6D%ui; z1D9)HdV5F@=#6txvVub=9M6k5hDU!`u;ESM4cX*qaL%?G*zD#>u2lrz7wxRVuU$kt z2aW3$W34Zw5J5jnwxmlYJU1#`-}7d>KDe`arV&;&HNACpb(!XgDIpD?hwAX*1OS0I z9kh}2feNr~5Sko95Y3MwG>#Ok+in}sdc)dzw42QwYy}I&3MDG$84ia+_AnN^*GY9Z z$TI>VFG9SgF19J&@t?N}MszTg6Z~SJ4^GgZCJ2)uq;sVLMxrrgJU_hq-(V#uY2ogo zpNpC)0l~u#I^wAg39VHf`S*+*Yg39OK`ldXYkSVdN-x-qh;&9@c(VNEKI|NG$M}LR zPo}L$f8Ln$kt$Cgb1nlZ^s0}q^Xa7<+|4yI>vzh$su$F605`nY>{2V~#HLJ?fiwcg z4CpyYGgwX1w`dn`^Yt|+$H8}r$dIKk*C?p83={ZIxA|v@8`8{Ti zk;*6o3^(su&^G@X?^`Jbpc-Qgxp2=?E0iQ$9R)Ig_aENlwO1%34g;)BG)fe3AhXMm z5&OeHQw6GeV6o@&o(6CA?t?;F^pTU=uz;&`;)Zun~HA!?f7?TKP-O&Mogr)ivq5-w*k?* z^WNo=U^35_y3GUE^-ieU<9`L8+! zvSDHG3dGeB?rlqa$!sltRfjxtl+&y{cEsrgcG!CMQTOzj6NUC5(4H%K{_ff0V60Nh z%CAVE82O74GBX+|Quy#vfbifdpjV-642>Lz*;X<^-g}9E{`n@pwTNq{Y^%0qMdxYo z*2TW;Xumc9g+{`5d~5r*`97-^^bzI7ThZ=4@1|a?0Ne0TpOe$5(NlW+qY$h}OAz!T zb^cXA%k9{tbgsu*62fzAz2R+sGWC>2-jOyXkaWQ21JEf1j{D-WjR(R8AM1kt>A?IwMF8+>_CE!$W(vw(eh3K1Q$4_?tGS^zRl+^B zzGy2P_h#dYffgq(vk{;&2E?23^<`*))uB{>Yi7)-qM%3k+D)QBR)P^me;7kI6X3!jx0s_QovOCM$f83z^@!< zUg%$}cW*vwb2`}L8Sj492)M(qeX9J@;|w@g+TSIoV@9efC&s|om4U9Qu?F}hV9ff3 zSpU_|*wE+6tne%zG6w7~4Sa4Lf{oE-xn&>!c%+^W4Y;-}jpp9qI_wU0V^Ixvn?#mB zG}b0Z)KDW6m!o?26uTHTK21{vX=X%V*)sQ5o|)WXZQ40^s0WTXUG>XmLh1AjTR>Y{B==@#XR=ANPd80VDfNj|uYO5SpVy-|Tk0&uq(pYsZR5 zi|NG|z+f<7wWqXlhhS^z**QycY#-6;a zshugX3sM2ccu_zmnNRfJ%fPGIvVmcv^@A(Za-tHo|7mXapXXivLIyE9u=`e=%)~C0NZk8sH)1%FMmN{%2q65pIspTmt zvq6aW7d|sGN_Kv`u0)2D^8 zr~r}%@W5@h%1IAsO8$KR^PTFHyBwST^w`f3E_iW1T5z814fdQ zb!4e$TB))%u%TjQ+K1)TYu>vo2&|S@cU7L~4mdkdp-)b>E4!xJ=YNoP)7OP3A4j+r zQOVocim~MU`2hXbQ&)diPyEw}%iqz|pKzV>`t`rC1nR&a)lNqfM?xtJ=?B`Ww1Cm3 zPkY9w@r~N;x!x-?2r3~?a+Z$!F@e8%G8MYkk7L<3k_B05#MG^D`L9Hf@`|7G)sVbG zjQ5!_%n4QWm7;gM&qGpAroOMnX%TpS9FTLUZC6SM$t6!-Vw z5U|XUHlm=TPEGtS?VFqr*nB(*Rdt>*V@vXJsCxDCYTiw~) z6tHv*>T^giTqe-RB&?`1z-uraSYC`7FKcnlng(V{E?7dmT5j!UxG^W4#CTf=-1QGS z3J}QA8IiEg%-^i@p|WnZN9?uhlf0^yZeSIL*3b=Q9zh-2k>%=VkjLYTf%*Voh27Z{ z4dudhNWggZ3`heK@Su{2=ji~{V%r>W`cx+9r=*u@33{R0jESoDTSmV=0}8jE&SIVc zn!N>TX&d+3WkyU(5AcbJc4!jSpUy?gRy5UjvXYOZqMY8Qn9*S=YIxL15%Z>Lj~sH!-UF#*;!|^zw7Zn=SVB zMP8$OQQIt#6o7STaZUn_%-!UWv98==ze@Rr85myZc5Oafpbkcr?~3BT+hxAnIcdZ9 z0-Y3eq}4_gV9s4oKh2nVNm*nL5eE2v8XQ@Nt-qad6+HR4zX%(dzwPKEeI#RaGOo3$ zK%Aain|}K61sHIfQbRsoj{+8Xt9uyLe7V?Ote&w$*$~d3tTcKfFx__aD%VM-bHdeg zAKN9?_=GgW zRDh55#7(iFGO^Qav!KJH@q{+6<8d<5YbtaDS6pt-)-_oZabUncZ;^pFwRFB3R4yqN)4BcfTeD7`e|2hwcJXA?pzp?p< zT9z?+eKZcKGZH#Z+PQ7rb0=dl3KVmV0L%s-DEQ+|w?k_8*ZVJiM@fH;SoSWQXhK(=uTWr{O z%eZO8EnO+-O%`K6?$-%Ri2vdutUPVugz>2^JZk{lLQl3oXJ6|t#)j&$WuHi4BMyM ztM|w=C6l$YD`SgIKjH?zPMZAXYpoc1V5&$dvFx@VEGlm$H&aS)cCn$TGnL#@!AfDK ziG0Mn!LI!!rwhB=vk1#G6JxV=*Shi2wH0cRuXEa_*1iu<91lg%p=l8eGdby$b1m6jh_k^`EU3Ja zRb7i-Fr$IfD;F%O1XV<3&y2^OEk1Jc&JXXAbHl39Z5Z>RNs{Uy-YnB>e8nKBN4+3k z%y=v?>)@h+yd>91S)S1XXeykP_3Fc7>=x3S$z?@Ab@mGdc{1NbQB9@)(ob{6^(lf) zWJ~m+M;BhqLPEunDkQm(F)tmM2OZ-IAoU%&%vyK&Aa~v9r?0i%Z;%*p?gk-`M*;Kd{z&|BSbk57S;4NiP}@-rZF@Nws3b1jhsfv<$}h z5)SvVz@N#@8j$1eZtS%{k8M9w9C-cJ_~|>Ys;Ae>pGLVc*u-h;IMJ+%K+n>w*JcUh zDHn$iQs3|6RQw$^MQNm+QzOb((@3#9=&=1_rxe&?d8&jHqfFRh@%hqY*`I^XjCzWr z^kzyFCHSJRJ9LV(!-*9>8}H&u3A8ipX%oA;>OyQ^=5zc}@;pNDKJA{kV9uq^-@+bivaJ3F3LpEB5BX7=wU@k!3mWe zsF-q)_pZ|H^mYz6SqWZ~g}GtGo>aT#g{e;Sth8($m4zj?J~;i<=V&>!k37R54}*SP zR(tNJ+dF(7f=k~dvd z)}GkqO&J28&HSo#kW2=mx=|n3KSHsIU3bqOhvOJR)kR zBk(YLJ+pU>1i5!D51mnqHijN|3t%;e@w=cPziq!uL4Ke7Se0OwXN7u;;nOE;tU)iS zBgWr@)jxVGv)vgXuczZ}$-p)R7UX$S?Lo^fcbi*1l=tD~?b~iw4?ztlF6P2$D~kvRc+)BF z;HlG+O@Hdv-nN{c(ZeA;wxmG!u%rKtjuWUJl7Kqit^`aq=W8hN+QO54xd0-CEiVrXgu!$y8I?(GkS zj({H+FYA-94a8UX685Yv>Ig`I;BT_KK>W0qI)U4K;oXyNyodfypJ<-5^YEHY^(YtbYuV+a(`280YCp5F|QJi6EUd8+Z4MK}#`ShNT8oKTYlAhJI91 zkhH0XwPtd;8m;dwjYu#*)E(*@b`@941ivv3H;7I)-0%?2%QlEG_hHlv+WZ=$1Lhui z_iM`I!U}lzDrLaPzT!`rAv&Gbq&=2qQ>bLzPoFa7M&1`f;ZmdvJ>D_Zqqm5%5yY0t zAJ1J=oR+uotx2%<-$n2rV3xnf{GUZRe|h4+pb-ehAB|PG`o`_o^}9Xf3ZA1r?Gl_` zoK=<)lQh4+*bS2Vd5-$ELpgUit861YDR13q5 zCq95-f0ReJ?+g5RY$Ie-<%z=y<(vB*N^IpiVl4G%A461ouz z3#-n9nefKj^LU~FDJnYV5s_*(d0$OTBG5k-_R_!fX-Onl<7U9l{38utgFJMpzs~+j zjRFfi$zO!x@vQ|3U36v3AvHO6($2zIhC~dI^9?r&N&K0oDsF}|I%CYH!f03*Z?Jjf zxZ%h`bD4Rt2<5Kqe~DL;PCYBw6jJLTJ*=}~eCFGP<`g7I0=RDtA&jtQr*OnCRw9td zqQlFA^V~X2M}q10jSKKHxJx95tHk6(SR8ryMe{_sW3j^z0Jl- zQXu6~=f$?}yt;2>UA_0d_V!QalH1?aRixjDp~;rQ-_d*MQ4CS=e;?i>-Un5tMI^&_XgEmC&6O!Xmw-s3#_3*maisx z_zLs3w7OC)6CHs#5$9Z-5Y9s(j4p^~uHs%8}heD*{!qsmOnzNcw6 zc=2ea`O&--N5ivrPET;*$-6pg{npz8!Lz#FN{=@>*9znfxl7JFhSS__q#M#{N|G)M zMygV-41&2}Imh#c<0`)>U>)`Q-q;`Q^~g?HC|$~&*$}Ei zXQzzmRvkbj6g>AoF@~x$-}O;^qzz5kbgy6<%88`ZIZGdwBBm!u40|7NT;i8_=A)02 zCRF9@ycSlQsY|)(e36O7SLq*V_fz2PY$n}FT3{CVcG{{=GU&{rykeB9FjZ1yv5!rv z!9G#~E#(^ZK8WRP;TlI$d*&`*9m03jiB36q5z!6GL(j|A577<_TP;A%=O4VvPf+7W z-`BxDA#@NRrW+my-%h6qF;r_x@8JE6@LG7mN&{E8QL3nV6@QgFTdQRorOMe9@ zzb}5nLLFItUlIQvQT;x~|0AWw-zsw>j^dR#dm$aW&;H%W9>Lyjq)eUyf2$>I zRM2GwdB-0->R?ZP=Dp{2JrpGPV|w2?9k4+dMIXTtW%Mcv9OC2rN?TsPOS$=c-MFKd z2pVuL1;N#!DiXwdbIw<>qju~d^&}KnL&b2&_&Wv4Eo1xsO6ON@BkgWb@!DXsZ9IBz zi+*Nb6!>_~TY0dz9e<^8Hv z1q$8)%{Chy(l}EcUDY|c?IbDUvN;3tLefa-b-2dAZ|2sI=Moe`-G@i1^_5=Ee^RhLac9isM zZe76_IAb}g-gFj`XDV>qocT%Lb6(a|_J>p4>uTEZJ-Kz>d{yO@&4O;p!)yImkqn$y zMxv&0N;l%zvw88vi)>@-1?ZdoK7g!3MRG_`YG&oJbJtFlZbKMRSoV$K9FlO+@J&N_ zj6CsqLGsE`of-+e{bJYQynEI#4mOB7{lTo0YLM{F=$sdJvbW?ni@s8W2m?TkAe`GlykdV&E?oGjc}={J64OeL>8+4>J)*g?d@X^P zEPh(lN`rqEq&;s)>bjLX_!x!6NfoicSDxLb%4|Icv}u^FT(yI)w6m4KZfqng2RtN{ z)F_OlF98VBM}}~mj+Sd6oCExXrIKe4gCE81(k`0vBn^@LZoQL{Jv|;d_IJ}MT`aj! zsc`y;;@8^#e9uEvuz2j1P|b7Fo@vwu`$>!bP%qDTEgXag{6ys_%bV7``Z& z%gM5=q&Zz%5Urj#JM5rg~Xt)Md~dNcZl($24x6~rq0_HXnf^bIcU z+ng?!-R?(Zo|%}KO(n1QYH)5};at7!_9&wH%*5m@ntYeOp|bOs^6Jm^yZ4%rO#ffY z?B1gPmcLNgc(`rAgJart2Ka?YUmU5#fIq223w(8R~)DKO)KemCe_knpP8HYl{{1sDVJZn{ZrB-x zo#{?uxorPg&lu9p-4u@xK-0e#MprFBX}-U8zz%wMA$q~QOiL3jl|4Yr2H$x~h*Dmv zI!#804Ykgnh|H=D9Cv-t;KK^r&5an!SOeAdv7!|l1hdTaUQO%e1@!y@R6Wx zxtmSDvMo=`!HkmgX#n^$!_pBWpy207Q1 z_JMch;Pp*X)S&u!pI0s8yBh{r-NXYLS=tOn4!1xI42lHOPm#nvoCJC&>$H$v!9@skxFWn4AK>f928 zV=kB-V69{;OG!(WT`{~qW%qUc~07>8}LEt=S-V$RRv9g6B8&YX{h zYgtBO(^?6;td#)=fpR3`tHWzkcZ!)x6AV+5HHcwaU=&yl52m-9CBS9&SeO@=y6q4yO4fFMfI? zK4`fdeK6bl5zF1#=u3|`NL}NZmTAGjfeZZPt)BvEXPVLB{;x@`_70Xq=kVs^)j|_=B)FGu#tpod7d|u>{|?T*k52(PFI<;9IZ`fAjj1YzBMvh>X1U^}6P|bNM6qz%QMYoT}c{HL-w$b4BS!`$H)X$_4BeD$$f1PWugo0EWS%AUM#-Cm~dtY zAMDF+42lF<&-LN3Oxs}r8b6BtdD%DAzB4Z?+-&pGob8hC&7KI_Y_&Z1(-l_~uRF2$ zCUHmzO?rmz0+HNXufx ztSM2-?^K8F8|R4I5UtzTqzl~NDkilaBPfe+o(*0T2-{h!Q`a0)uhVAssSYe7lZ z${mJ5XvQVn8n%unM7j>U(p-01R{*UblpJMD@}sN$4_tK-zk+)O3w5wkz28FWSy)9< zdVTsSZf{B}?hRSpVg$=uxT|dBQD8|aF*;|eb@aqiZrBIo=%wT}RpiQ@MB{6morpyihe;<4Q-+}r682P^|4idZZ z&T)5Sy)IYH1!v3ug4|7`Z>AqD?_8za`B}9X{7(Lt;#~~=A^m7&XA}9Mx9r{a5K8(b zxAov{PI@*shltKI98&(5JlRE&I6r3ui2w+mp_O9>rVzg(B!590?@) zX-X0?Dms714@davsjj?&0hY}^@wHBYMe$~H=h*msoQej;O+NbV2$UzlRmK*XAsQ;e zTzJ5c zkbi*Sks9=yYvNI&3}E3~KvhDBqO?w6zp>9xLH$M6{N4=fh}2tQOZD?LBuBLr%J4}sL2CvIAFgnj8AoqO+kQHeWRlOtMgq@RNB50wfpUsk8<+tNW!u>BB zN0m>N(hn$xh?a|O;=%q0Khma53-J8t)`X$=GKg17`?zt|)7=r6`4Mph_VQ*#Rd*vY z(EpoAoDl0qR_#Etq<_$3&ceV0`lV*-^$K*xNvhnGA#yS;P_T}{;4RS`-siA|NHI_c zoCZ)MIzs;VgYtVzPRA0A`^oLk%2sYV-)#iHU5;K&tq5y_EJ{s! zS<8(s73q9A3!*g2Ye^f-ayixpjf;I%<4_Q-la-@Ir5Q=f%^OSdK4OZ#l6;~vojbiDHnwyQ`!^lm@{U4rjg9;D$G_YSBcf@nhGvJz(>xpe+gUg(INVGk%4n?ccKyNSoE4mIlflah6W3=x(92wC zXzUcHbXjp54<1*TkenHy_rB23+^I;p%IRhsaYzICJo~=OYlHufG!uVKF~2K#|HpIn zmnRBY;E`^jR=5P1S^**wJAKZr#b+8k2;dpCG=a7w>I*DH4Pw8MoR79S+!D)CRaJp% zQ!y72-pz)czr=<`8gZlVHBDN63?;Cnz<2>l-ehA~L(zU;Iup=5XahKJn`3t8ahM{8@MM5yiglp4q;@Wu)IViS`1&-gu4WbTzW{PCzeL`50sZIPcPhJdZ z4So=+mxnyqNrS`2lgf|>NtLaN!49h5m0oxpED7J(P&?r-)cjskDEpXi%-BUjw@}P( zuVRL?dcjEkVD6*SX?6-Mm=N{rpi48tA7$H`MD)%Ijj(M)&{FSrX$fVcSef?=rlkU@ z+5?i18gF;L)$!gFh0A4i;g9xfraw-mwN|}ek&XguD5%IE?;f7qWxu|37q5*qg#bbp zQ3+H{F-eu`1ui;AEBX>xG8LyarDqZO#8Lgcy}l@`>U9RxnOqj;0!#YpsPUVxU{if66qL8}OQ#^Y^@~*0B_2 z_4Mjf0^eiSEBiy?&)*wd51NsW|M18DSNfp8!uH=3MLJ+L1rXM^8>({%EXU7tD&{`D-^9riY}ASuo_&p#*qalh<- z!Se}ryIcyLFijhuxa{RNbr!fqqZ?Pb^{U2 z&Ow0Q`%GORvUfjh26?#~Q3OToDb6Wm15~6n;rrJ`ffaiNzVf=peVdOm&jX8)83lMY z6)mi5w)L4fsrD>wF!yt!DTI-}y{y4uA^dF2D-WF-rsrGpYV*2mDJX#oyuR-;38A)e+JEbzlGtQ~sa9Ft3#x zsQ_fg42uYvywMY|A7uGt;!vA$KdcrV>%9y~DaL9;SE`T;l799Z#(C(oze!$v4mjtN zG?eYXBx6TaZn-yc?g(SXw$Z*MT1L3JYT;b+RSG~I=5F;ZSYC#l_A3tSmEfLjGjh^2 z>EARdeJ48#dt)>72p0^7iWjp%a&P+#}Q z2Yx@0J;5WG-5V()xk7oWs`iZAFE#_~P(r^j=mAB(kTrCkY->MB5jJg)e%Rw0J$-)M zCa$o2CsWwDr+$6%+&kof>+U6DSO_monhKj(B@?`W#en_z3ocqjQq9Vk-6vO8&XCbZ zs$Y~SZqnj!FCk`ON*f~}`~}Bv_CnfTbHruy{p&#L@_M83G4g=WK>W#v&B(=XkY-bP zaz$6cOpmt0G&2Xxn=(J{6}8Of!IuHHvDR|!N0-b}kK^QxWEuUr4lcax0%501T5=~! zrWZtT+s^2mk=IO)VaeS$(?2*7?kvAft~=hl;%aG?ezH?*H9SioPxEN-Xt(E-;Br%s z5T&vDI=e(Z;xQ_9*D1n@#!6=9fL`W&!<$ZhN|#l){$NXmiCZ%}^xo$i-ga73uCBTb z2K&)WjLe>pU-Up;e`5`yg#lNEbnPF(l;45*e=F_$+tp21h|kqL&S24xWq_;8b2c5W zNyN(Te2Ko#gW2&h5|eLz8sct5H7puCRR*iSJq+q4Ihq3vx`UZA8580#9eDNheJ0sF zP-%KDS-*N3A-)T=v$BN>$Q}S*GIm$AECAsqcG?{`30V@>gnSL}Hh~C~A}JiJ#x$fI zhjp9NW%;RrDoRb3g)z}yE4DhfreTTCXVxw9Ts1!i)jKnjelO}HDgUFDo;yQ%_1!u$ zkMnuh5NQ=P-FfXm&IcfzFbZ4&;%7oJYRC9y(5Ca+MWQZikTp6wYI&1rznI(zF+L1n z($g(?YAQd=minknDuG0?XuP4e&pi0#W|>nCf~N&nWc-yxGiO_T-(~|jVH$P<=T)!C&*>p?vr3Q(^nQUmUpbq(y|bU4J|)FUpz5kkzq`; z1=rb8PRd`2NOg!iIVm!bu%(a!=gCR!PI~D}VZ9-(efIN7sC5dPy4!<&Np0+&+-V%H za-;-#Z%dC4T}1v=FwK!9hfG!3)RRvsG2~G0;r6{1U*sSpZGYc_MV*<~%3|L*3~|ZO z=fFA=U^F9rha7-ZQ4*u#t5qtmD83j`tX)Gm!!16K@Htbimtk0t^n5Um@iB6sfAGo( zE5Kdi{hK(k98C`3x^O}ip03S(O8Q+afi^+gr*yJU>ZL@#poX*xcR;;Xk&^CV%nMZ; zH3e#ONQf*pi^jY|7|CGiZ$>zFn5Wwr_r9&pU$-5gJ<{I1heu&A(G{5}L*AX127$VE zom$NyZ}$NJe|~#mvy4>dfAL8gQ$W(*Xl+~kp#?uz7d~i?S>ZgBWbp9&Li%*Rv8d#b z+79wvEeH`#GV|dfbbLW!Yf%C}47K7dia6>?Ir>ho`XV)KYK;0)ocn7QCKUTh{l7Ka zmlJ4nDnGZ4?E=k7L!z3gVp(lf>NE46+8XO_1V>sx0IclpcOlo$N0%nfd6rMB?|UVS z*bDL?_Di}!TDy0mk=5Llb_@HXxHn}^cqkaqQU1?r_WvKoFfwhrV)^FwOb3A{+v{*r zj=`)4;_L3;Bv>?F3ux<@d2`)jO1$0-fEMs?4nG!68A45T#%SOZ%p{8z zz9dJ%Y-M(`dJ?Uk{f~Xmb*sEvsoi+1%Qf6w3uzBhIPy7Y#>=`u%Iv#5wjSA7G?L<@ zZAPA8#|wL5SHe*k^m*#52Nu!(Iy1hj=9|8eS+6t|?O%oL+!%{qQ8_Mk<28YN!j3Q4 zR`n|bf9d|TfY94W>=o#}$bryOw@Bd0I@wO!*gV0G_!rHYjk;O4f<&_Svi5Ci?2YBg zHRz9@MS|T{dt!?T4aY9an;8L0jjekXLg*ic@O~1lGtC-oxAU#CtrVd|2V1MAKu%v^ zA}h=cF9RxU@JqCIag6~tkB6;*nkd>BZQPn@$n&LIMC#1egXceL3HP*xZr1FJue?iL zHFM~1*kK%35>-B3dd6KA2C{2(z64)r`O;WyIsUN2EB3%46>~6Vgp)|Q=2-UmBz8@u z^-8Gg6TwuqkFV9`$pbN|9&xpi;Hsqq6`UCo#*ubp&hA*5#IR8lP-^|*cf%Ebf|UEm z+U@UTUxFCg#iy&|O=mDC&97m*Me=5kQO|Z4PA{%1%?L%BUtjIk$PYb6z1sshzg-w@ z>m;Y7=WsKKcuw@=i|U3JroxE(t%1n9U) zKssY9aL>$rkmn{}FpISEJDs-WXbxh8QxUY~emY8imH6f(|8UJQ*Ilo9E(87&c~5%y zRpnU29smN&HVPPFB3XjQ5c_>*3LXAov4cJ}<%QauqO--O5J{5u0)P#UzBa!fgO`Ub z>D50ogo{8+Kj!!Y`Ih%G6#^pO2ktHW?%sUKIFCLnjpk!NZ^`HLIUDC}M)F&dOrnIH z+1<+ghlIev0rkBN8d3?S%8my^(l=A|dGnAGONm(MkHuMj<5bDMv{1IHRDipM^zr-6Dfa3TfQ>-{Zc_fJ+D!hTC`R3a6nI8zKDrv&v32dF zMQP`m2Mk6T51(%2?gyk^{vYa#?zf&BHEQkh<6XNLK2Sn*HSAY7ll5(Oi~JG)!2am$ zhW?0a+O)H;OvOQO|HHhhKqXp^o>r}i1y^3pXA37j`YnSp{`=-cxpy}YI06(cM}*Jh z+H;!=KVLAZNr3BqfxUElTnOq0{j4I+6_8+ZX|+}G}4eB|l> z-x)PpaIhBkIm(0Lj+j4_-m~vi@s)YnyCZ7{3Mrkj``ds{hZpnX3mjffiXzYs^`XG# z%TdZ2**=61-4Ql#ed-z-=&)X;*5?+0Hk>K+Qz63K15#)H+ifL)^1u;<0aZzk&KAP^ zLh(cPsi9;AM)+^6t*YK-?Oc+u&`^{id?mSD@9J5EmZ1xkiN^!kUO?J!|9L{{LLOeS z03p|NPBciX#pbj8uRtHw)LVEOBKnn$J#pf0Fmtc5*hkB7pW>wa?d`{ zBQ%QX=3ipbn{YK3u|@OnjtHUmKCW|o_Bt!0@#M{v2)e2W5n05GX*J{r;Tg8oXj6cj z)d394EdzF0;IL7`7nzo>F@EBIs%=*Tiem&Av9L$y32dxHW+Tb>-ZX0$=Fd%CsJX(l z_))x#A?Mma%a7^fw~=7~L57~y@xou(=wnsE6Lw14qyEm!rS z(k&B@Wy8->sYUN{aNzE3TZ-d~K{fXdZIxF$Y$8anZP^s-rnX`D;F}e(C%RnXDf$66 z#07zgZHv)qW@vfxnv!0wGIf7w3_!sw&Q<~VfsTz%WvltvHg|aTM7?Mc+aXioboxzlA3In_gE|-p6t};z3FqiiI@?;v0UCTWJGX zy^FkGN=c#-z8a_7Xn3;9T{iwD?j%YaoBfP@5^RP?3oDY@>%*oKeTz_t6C^D}3D}XN zstjg_q!M8{U@kJM1YMePEsO5b>N@(+Z*MinT~@f72cdd7m6o#w#STX4m4j6@t6#q* zRRsz~EUt|GJcxMR=)bgyV<$~|iW&tCUzxtxRxTiSd#JuapAZF507LbSVWMg6+on?& z_fZ8Sn*#94x%TNS*X(!Jkbf}+_rI#o|AU+@2u`zdG!B%X=c2-h&#a_dsC~*k9@{7B zyat+bBr9mjPjD}|;*@HCtNN2UWT6+kZvoF)WhLLvsyr_1_Op4z1N7(Do#I5!z2pMs zQ&hY0BBtU}1HE8T^h1i$NGzh-<6Z&cC9;&_u>@KO!;O~RcB$J#CctC-ACLHD%p;n= z;rZo^l|L1PM@EZ@lem$Bsb|l0(4xTNw>Ju&|IijI43VPw=oqb16I#ryIC5NS#_3SW z0M9C|hfKOK0W|VnzZY+cGHlRi+iX4W$ao+M&_yl6NKuvrZy^KL+g7H1SX8Q{eKwHo zDdJ(^LRW?QY(mNKNEA2)Zj0k?B3jNIB{}&<0&{hV-CgIH;XdRWVwfdn1vP-U4J$4Z z$yS5#T%0*FA`GE5Bzalo-6hf?Tt`YLzA26_eX*E}0 zz0|xnnrf>xD6OQ6dmq%YJmQ0^-RZ>YNFmHZ}WVS9^>E=M=Ww?{?8)x;yl2Fy2i>a?k2r$(sr zp%s_85#~(di`~1ak8m*#%ZP-7xp6~BJT9FPGWcfeB~xS(DZ4@)5>j}`Q+Zp_R(SF8 zaf&OzCm(aRRsY|NPhe;!lj}b)G=mTJ%(mF@SeIx^8hIi@Dsj=ZxCCzleGEg$U%O#_ zZe*%uEs0fg&8!Q-8;#Xgl_U}E1qcAjV+N8o1JUEa(XVF=7K!Y*L?Y%_Dm>nJGs4A5 zq0^mIu{>XZPel4!YK(Z(eK!tA-1y{D_W^Gu-~CNpQ9yRmrS%7XsTg}_m#FxRywDK- zw#18>#hxqgo}dI%WK-mOS2nU|3>=42LN0NhIUnD@rJmu*xv=^$a;#y4IEUOZs ze1ZbQ-r%)ZkHZxrqu94=&g>8W(C_hid==-0;{;}CX2YDnn=y7DGr)IV+)RD|^ey{61Kj&vj?J9}4 z;kabCHX}M?l1Xfw+TZ9A=ynpVnICXawMYbu$d%|bVrAbExV-$u@$ufIM2!h})6pbsV3(eD zzBb;!J(P~j)E>Uode`b_|NLvrWTmqMtmSA3ZlT`zn!fm=_rS}e3PU1I)F0Z7v#$v0 znaazFepzYx!gBoTyGCVj+&U8Ky*u~CLZwu+G@XiPsoJSq3&etdh|MUDk=;rX({&uH z)t0-5ie`I5dyJgcSW|^}%mojH%Uu$gI%=bU+dkI^+E`a6sbfF7cB|G=+We>RYA$k< zX2|No%^O(C8Cw*@dn4(?x3vwuz-YKf_2z{xn!Ut*IC1s5!G@9L?)XzbkA0)sl- z?A7uZZ@)=EUT&gr3Sgsy^?_Dv&zg&R9Z3(u2-LG&cd?U0cl@bLXrdnazWK%=2CgxKO}${hy^jYkO4>{u2- z(Cc3x-4C^5aWd6b^)-{thOxBTpHYW9^P^o5;XLg!7c7wL%_1|rGFe-?-WMK0*XgRy zemvpe&&?Qs&+J@WE&*5qxEQR~0|QH0ulIe=gtF9bW8FsY2MdP|2|x92o4a+%Z_rkB zgRlgh)nj0go|~t%i(9^M6wW<%!118~_K-PSjQNEdxr~+=N>wLRi?7^Cp3UQw(~XXp z(~zA98F(Mb!QS`Rl+gY8SPPhE)0A|J7X+L3g|H|gGOBP|3;T4nnnqo^Mf~_k_UmJ* zV{ZNtMYc(OVT&WH<_GiSE^>A;%jb*teb1UW`ZCB$^t;W;r7JIuK7I`5cH>`PgjB~- z-v7$9+`M-FSp04-U;jD!^+#`V-nafv`sC*O=ZoRL|4Qb}%Jo7=dnFPY z;fa*Yz1x##VpQ7iHX!!ACPr{2PU#m0e*i@ikdcgi5mSUi-6~Sw{CeX1*x9EHp|%=b+)BiXZO?VZP$bk zC0lZ~Tn5x2Bd*8}XncY>Pn7QUj1t_p@XEw!kom1&j$TH~*Qw*`=l3*LGweLciO*>oiJaq*bZcBiu(W32QihjuEX5 z=nX?stDt?R^vC$bE|7#i_%UJxO^2`t*m?1Q;@1w_u!7HU*anvyJZW1^a%tOphvy~d z;NwF$={4^d==ZSwA=*zLOLvu_>VL+Y4oQ;Bg3tdvJ#p0h$JfJ60$q?Umh=p&$dH16 zdvxakjXNe^w|L*!VOQkgMZ?RG^t7{jqbUX$SaD$?SYO1NJ$RVAaqY0-=T-rbP=hJ|>0^Xq4zqwwBlEKU+uNTq3?%OtJIx!AQe zr_1pALuNvO-TX1nvF#-eX*BJ?<3FEUwA^yxdV@%Bv@&b_s9^Uovc6?Q3LbQQRi>6Y4UxbK6}IA%PgA=9YB85KAXsQo$o`@vq6qU zX4y>W8uHM|?l1o%Oz%w^d?b zS zB{a)|occMh^cb?>Q_#1C_R(wE=cWLP?=&$W9UZDCE-Ljn?pD+56UTt7f&V)?Y8LJ^ zD!ez#CkO!k0$545!=|+vt-^BIGTGlD$y`%V05V4UEXjeH^jHZ!wByGh3uOrmhHuQ^nhvg= zp05w^s}m)SAN%BadVLIuMjq_rdDrZ;+oYP~)o%P#aT?DeJrZ-u8(d7DLk$HO&?5sri?5)1>qk5%ns}J>2 zBfB3OI|dj`d1f@mR--(fg-f(~``g_grX6zC<$5DjbG5H-#RBm2Zrd{$OWMrYOGyhXbwc4NZ5*OAIE zDH2me%16^HqD(S`ZQ;2Pn`KW(3*?DTPXzBW8PId0Q+x~y;VUupX-r2q)>+zRJ{415 zWRA@`OtRt0$4zbGy~N(Y*lbtq1^?uH{VT3S{e6osbHvUHJmhdvwdF8=%XV;--U`VN z3p>R9RswCs6Xi9gK0VicyImtR0!X1DJBiq%2sx=;3+zcJH10c393GW0FnXOwDu5Lr zh_P3AM=Uz4a${*RLfe))MoRWmWe4l*1+bJ}`u$RW(@i4X2UGFAsIZ{gk^ez{SOa zj2|AK9oRy+`CYL*QTuti9Fcv3!>Tm>7ps9*y8g^{Pf@HsXYY(+!^YfaX2#thSE`$| zsarT<4{%d5K+DtVih2!(NzpxyDcBe})dw{KuuK@)X4&VOxWMCx;ZP2z zuv5Hao(_^ax951exDT6_952sdcLFp^DXvrt(CWkvJ1w6|a5if!==H7$46nq8yuZ4S zBm}`e7I|^J`x({EPWrMCmadhXKn=Fkj=6G=jN41v#f-dknv9z_WlC4Z3)(}l=1Tyw zcn|m0putOdAT)R@-L{Cpu+TI>>8d-Kv(5}rAF|Lso~$DiMu`X8rmx4Na$R_h9Y)1i ztndF_S2$28|fy5!Rl z-Q-v3)KifLiAj<<$y|q+NjX38iTjg`fZfnGO7>}OyuD?(%Rr3lOtlb0c|l>tI{W3V z*-sYx+_u+rJs2N;>+9NYU#I;n&1Kng{6JTlQTxLPg{u8kEceFso?4>y_Juvy$TMEm zDnpYy(o9>^_E+{g+t^;E2E*fB_5e_^yo|7N{joi&`1wC@bN{t2;}013&vb=<+fi+Z z)|6F+bJ9@^p4AI;wTX5TmCLuGN7iP~4N=y5&NWE}yQW|dG3S2>VA?5@?!nK`AKzyV z4sKirMe&XvV2IhJPwI?4K}}8LWl260S-ge4$Ijb}VtGm?$+OgHs7#iPo?e=g0-#8W zs^lDyRKe{fd)SSp^1@7>6@e|XML2!>%PiI8k!$e#5)ft%KCFGFGN6mnz49vRx%|Nn z`OJN+$YyuRE$uP{?JWgrxtv?9+I2J{=3r$P1#v_ZuXxK|FwJ*Bp*gV@?2wZ(ooTbD zwH59poEJHonfpAt0Nev@xQDU|f(Eg%P&>_5(Pf|KU{W%sd^$>X>n`zM8)x8c`i+2$ zDC-7;ibewOhHAlOAKe6i%b5Z$+r}F%3eoZL%SoiJxFw78E*VlzW-xDBh5Lb|pUPdl!^^IgyUs}QfLRk091 z`c2U|?)3vKstDLyw59Tb`$KNrcQMXolVX8s0-hoeL5TQXW~KZ+UdTQov}jihUo00i z^rDVjvdA)j20^buye|O9s5$a@P3Roe2v_NNse-DjPpb}}^DM23g_b?wziczHpL^9a zy=1)ByZ>jk39_e7&d91xn+E8d6`6>mb)U&kgW3iRc{R!mbwI zx!PU z%TqB*AYGE(II%b|rR~LT*{C(krr7qVjze7!CUwmXUysu3Nw@Q|fI^R#Qkv#w^7#4& zu#g%Q9^0C4ux%$_@b0x%-LhyXUo<@a0pXM z6tiGZ3*`No2@BO~m8#;N20O8Z5n@xfnr1XKcNTAi(na$4ciJZe#CAZn@~$$i!)sHvZU5iScw6>b$I1_b zB7$+w)n&~WL$RH(N+#5HD7%&w5!V(JQg-GOKa=Nmkr>fWD<_f7WTw zs~6KeXfA+qxlWUGzLAPS=%vFd$lOu4QaO|$I}pK&TKC_LR=w&(-cv;!v&-sVM0}%I z+dOjXULW%=-*vxIY1pA(js)q2x^1AfSFlb2FKs%DJ9@7pT%=cwoL|}8jgdUDg1I)? zIP$SE7W!Iv-ksgU`O4ZUWcQI!1LVjIEsE*x@bdpQrUv=1Y5e|!5T9hCGTZOH#*%#qA3?A>@$w&AA3EPx;K|Jh}74r zVh3FIIxJfoR|j<2qM%P#TLcgyu&4y8FCvR~3aNK!nS3s9NBDUG_pS4%#YHMn%~i8i zjy5H@lKftcqMTmg@-oHj^v7-%!d&lsFpk=65+_=dqW8p-?*kv}Oyf5*FieY<~; zZT*2@{Ezm<#Q^d67odli596t6(-U=>u(fM@q(o>u?C{pqPG~YFaeQc~rR9{~iw||EFR>&9t!CZc1ptpi_NxU}rZl0_)o^ zx_jen2gP)*gHll~3>@ij0;?z5#m&{fln#KAF^suodlDAN9*Jv&=anv}8PvJ3AsaS7PdX8DbIU`qRveu&kDS@8~Mneo%Bqg@4!y8Y%1q0t@pa zw=>8%qL|rLz*e0rd)-Aw-3IU8CFA?2EJExgWztLO0k8n_c`(bP7(jlP;pnltBHmMs+O<0c&at~@+I^MlNE_r4i? zqOP#!#{SEXxzhxdKV#k0jv#f;t-VNJQWEtGyi#7X`Z)%xD7qvsFxF}a-NJ<6fKYtC z9dNuPW%}4Iir=ZmeKXvDSFPd8QNSsosKgSG?#d*eX3sP%!i?Q8S+#J6WfqCkztDPX z`x8STS5wCBw$JG8MwXX6Jla?DK-wATrM{HBxm&kFZf^WXm=U<{aNgnu{ljPJwzN!jQvi%S8W=Q&K`yj!Rh%eTcQ^^pFo zR#&MzCH{7G{OYsJL>@pxNHxqCI0-imc@N00V;+3@IC~$vNa3gJ-h2c8tS8R^MZIu) z!sNSp&=NPDnc=ZjRMn0HvY-bS*cJw@q^xrRbwaJV5^jtr7;K>0Z^Tr^AncUwY9bspZHfSZpx>EZz>A~7<0yd=5ud_=<%T%^>B(BQ zeYzJ~aUYu=bijp9p%WU(Lf!BO) zWS8@{KFA>iYyPQNdK>W0xa&*7O@9I!j`#CECd(FinabJ?2FM`(aB9p|8wG&=+Ao(F zZfCw5%?k=7$w$f$!ewSesww0q?C?9jnOz<>H|gA&vcuQk2m*9)gYf)VA@Uv)Y-9ncqPzM+JD$n&F>uG-!px)zi3 z$CAvnQoGJeyks{B7)rX@m%c8#HWlG+1Jo5g#f)4&G5#9zv;2R%arU?On``-8kW-bR0Mh@V~qukGcQvPXw7zt;->lvDM_a6d-H*v7zuogAE4}b=`;nPRsT`? zBQZx#%D8?<)BGF7`>;(TuTF|uP5eUE0~a}!`1A3VckaaPMTMbCat$Qx{LSY>wy4D%w-rzM@Xk1XJv zVv?U{CfC71H1sylADcs(Ddx$<1ItOMF{Pl`1=^MxTX`CFUmJow^BLZXv$hLNBQTI= zA2y!*Tcd&wiHfTv1B70V0XN@!Us?U|My!2|$2p=fS=gm*^Ou;wiFd+d5c-xy^P9da z3UB=?c?&DoZp)L(3~U3l$LfFf7Y(IG(cPr&6{qz!KTR$RMiN4hq=-J_A9>iV@*l$gB`bZ+0B({Hs;o!Qs`TLaHA z-Ofi#iZZ6FB~e4UxqvftacEN9OxMC_sM7T4@QiMQpT?J==p)iDwl!T%#{|qisca%` ze+T&fvo+s;y(s_A1p^?2TYtMic)=t3m(9v=Qzlu&ROy%d^Dmc;l@<7bV! zM^m7C`j&l0a2B~npK7ZPX`pO+NLtl zuvmD;M?!u1U8jP9x+(kRzHxEv;Rz!rVrmNQd=_Qj1aN-w%^YTob^z4cxq;$6n7lU| z5)A|7WVqjJpL)(V`fMM@;7a7XGol*e&1k2{HUDKr1K5c(r17ui74keb;yn5>Zw=VX z`JO0G95Jf4<6B;EU?LIO7ASLVd}~rC8Q(b|pDOSI;tvm^1}0;96>yD%oHR`RPqB+# z7nhe!*0{SFJ=OR6k|(>6lcjy28@JXm*Sr6!Avysurl(!&So=Br^DW;Ls&A%^m6$L; zOYH^pW+yB@;Bw-@HNG)-%+$Gex4piIH0?4!PjFu@k(+W%0k$o%Gjk^dFn3P-ja%yj z!O1lU=+}NM)N$)3V;(tH?2pjl<4r@FrRh40VD%BjQKymAD{_bXj5gWv;9nS049Sb?!q()^DkP;Age2$#I{K;n=^2*Hr}F-%@SI?`++5+QXvxLSL!vbg76#(PG0e z$vhv`ZfT~@MMY)9r!@i%!j+y~Dp=L(n|l#k(NHH_Jas&3=-kOwx9VZdF<&J!0WAxg za>$Z0Q#r9r>qkAkW1p!vKsA1COa26c{Ced6{{!&A+_+h}f7ST><lT-+RsN1#1 zAG4d}KRbBV8m$4AFtXMtt)(*57~g?eX4Hvkz(yj9J#@@m%snnPbA2p1ZmH?=X9frK zs`1%+Pgb)PkocNg#%!In3=%-tY^2k_-mLLLyGoF?b9| z=?Dw-h}3z{8+C+b$dXcTR845*{j$5k-EX2P=rpukvcOvFe3CH_Z#GkcmqLBW!C)>h zZ7;X=Jq-F*|IYm@e~0Mfi+zvL{_`Q(*kJYtcT721)XV|4suvQMr@UylovcL#4mlB7N+ z>Fx#3J7LGH;rn-76Sr&OxxbP2P)MSmwpb;U`@k--BIf(@Lo~_xC4$*{-FzbHqc_6m zC2_p^;%_BfG;K?-;>TUD#4amU*SJ688bUmFy`N^3Hb2nw6?%0~fLF}0l-oU5TM?}A z=85>f)O_23^Zd6Xy@F7;F1Wp&kHc4@40kh&`y0)vm#zNVhoGlYl8X{$RyP~CztNqB z*jBHdIeK=3k9&u@$5UNNKB=cxfXWY`(6I(Aef+Bt;Ec`)KFdsM5qnrce zI;V9+c=Xvs0PL$8ML^8*;mN4ah`v)FZA$F2TjFMU7zObGyqj`LT}b|Xf6|-EM~}{)8hIq~vC>96ieNl+ zVDiC~S5WMVJG|R=%0knPW5V;XaX#lJFI(2MH~jM6ys~MW$^;k!o|LJFyhzv{%VD77 z*+8icMKE5VkA?x!73tzlltFV;AOi4}9$=jI5C0&(qm2I2aDz05wFlN@Vaf+807HN^ z8L&q{RYg4Y9T3?eWeK2g&RX*7{xcd4CCM0B5*oPx7~Qw-es|$)Gd?hUySXthZ7W8# z&|~Gc9I5l&lhOg!olkse$H{J!$D`JEt-V=S>C($iJ`U9Hv6RKy*+EOj*Fy*whf&Hn zEgheopRYl2;C~1!T`G3oez>7BtgE1sc^UO+@w)tqX+qBT`)6&UgpJeZ;~(SIn;J^< zl*aqE#(LDPr#sqyN~$@qR&3k${|xTqRY-mIpP$nfYE^|keIcLo^pvYw;B$N88cq$e zX?}5`Xc%7qL{s?yoUs-9VwTi>mWGN2u@Gz$hNy3iG-be36XEw|GGJL2Xy)OkkN7?w zY^BR*L+YPB+_Gh3-UzL0@rA*h>T*i1IJW)(6=-9_AO{9Cn?n=Ny)+tAO8WR?YN2=Ds0uJ%+VE@vWD7Fk} zeJ>fzk}hW|S!Z0|t?l25&fs5#rF-^-zM@t`Pc z2?16TSlo9Yglepo?BZwV?MJp%es4S(GU7-itmGw1iYLcxM9`RTaE8#g#*{EZ?x@QcT5R|HZMF?#nQaf$1)AS>0>juG zw=pQ!?Z=|)i{Wic8;to+2EE)R#rz_R*Yo|A5g8YWmzWn)(?4I!oAw&A^y24ryHTTu^GN{;4G-qVB4zKu6fzuRQ%}4dT#b z>NmyCbQdPmxtKGVzpPCDwJ`pV?e`x$!at*k|IwlU(P4D>vflj*V~fB2$N#drD``M2 z4{m?k=t9mpncM2`ON^o91+a6->^x2Rz@~`dWBGiTZW1%c-ke#EY%`xE2_+jBs{t1f zJCwPaF3NJ*qH_cVVjwCn0b7bYzE-)Ua}Ne?42aGIFW&%@m)SCMR?m-)SEcc$@Dgx6E7j|)5bwH`v27FEp^7c^tdt$x90~8QqMMBzeFJ?|sp1?HT zoF8(r{XqFvYBy6$2q%Q0fCkY#r1O!Fy-8L5>fCFex_uQ!bSr>Y*A~&I1z0{6*_W;4 zNa_R1!D9({2vz`d(H{DJEjkn^67Cy9zs-HTzc&2pWyrx$ms1wVwUa;=-%?%z3OB}A zPH+s(1a@K|)N_`K7FXmcM0Q*u<6drLZA~o>d_bcLVs!UrR$HQ|cM8LgkF_E?WgPQg zY)j+Z65jlxKolC$1N;=8$z)$SR^zK}p?8n$s(im|-+ei_*^5!w*!(^7klLkhwQBvM zX~z%U862&34Yl@fBgW6(sJ;~qtz3>{YGw!BG~Vyo6AmnZI>~O$YjOh!f{Ijqbm4GFuzoPd0lnb4>Vd4AAxIqGWUNQ3Snr!i(kL0$>B4YWL+Pm|AC6;m`Er;iO$6 z4B-3Z8eZubWg((&%`i)NC1B3(A%XUvt!PuA@*O^<@Se-I;ppi0gloL-?O?CRgu8Ut zDgsj$icj4|cpEpU=c~l+G1w`xjP|E@KnJ*qh632fat!K=URA!)<5He|viYfrzMTvC zK6px|{vP>&?F(IuqK7Bj^t+EOJx8^bbQGR89I%Rn^nii}CegP7V_hhvp^w{DKItOc zEHr;Uu-|(ZmYqrHJO|$ny&{`+vB?WMsX4OC|C?ANzdJT$yYBvbHouet@epr_@FXDC zfn`^gO}ioRV7?basVD|w2s3Aa=w?~&JD4Nj(tN;R+NqF$Q0?L@^9hd#*78c>9S?F? z!*r24vzwQF%Zp(&xOim_2pJ=?g1wxYuJ8lzFZ-Qt^&+H4yrV@Dyz?I+uoML1t_?ZU zq4&Krb6Kt31gC4^WRu!UDpkxnZt@W}G~D@pO>vEr9E%fW zOQAu?Z<=SD_$If08yX2^3vDQJsyOcd$(Ts>M!5yfEB@N26!DMfSdUXoGVU7;z^zm3^(Mr1r+K=K9jhgl)@_j+Hn-wP#v-v($JfiUk&^k>2mXgMO#K&7k=~ z`%>P*Br|Jt6(AyMD_DSBBVsf#upKJ|R>c-NBCN=$Hdc|ZH;cFwL3|SpHH2Oj1guOn zEE{$SVkp@up~Hf(pCB8G8l%$Zce@3r?-y%yS8nyn`XXpeygcGPiWk(2T0dt--}l>`OTI%UFRuGLQLElpZCg)oVe8NKznJ`9UP%9ZvZ z#if;O3zs-Wr%!-4^7&aECM+8I6fFI-22=7f8Z+}UU>WP9MU+VJ%>nj-{+=v+JkU;~ z)=7dOtw5}!4nxF1ur9X2VsqES{Klu4?y~C6PpOiF2Zt;9DE#VqWi@N(tx>?y)C1a@ zY6yh_%{F9P;gJ;};N>{3C}GEa*FX&}K1FT;5Z&PlYFi8xSi{IDL`U;%-?}KbKOpkf zK`$N86ud#QcJa1*Jo$RIH_%|!i=XY)i>ADjS`2fuHS!DUo_rKAz`085l6^alGrJEl zQ{6p+p1)Uf!ZtB~aoZtgD(U67GxW5S=@Rbr&eD-g!EfVVpUsImnha_D7>RH%$u(G# zR>dF%MT}kZW1&|>OrJICUJ$MY&9b9iQr}Kx36KA0(&^k>>OZ%57QiAhp33JHzzUJC zOAPnL``k04h|C&MK4`Ea9ZMsCVQ(RYGodIj+zjDD#??O;?w;IY_c`+2;w7of-s=n- ztiW$kcWw0!zG(Z;F&9`wec`-Jn}cZ~YggIX5k27n_UR@Xl1;a6K6xF--*|D3aeO~G zUvpshGec=@?fr!mXgSOCY7|F38qByS0z z$8%bUm>^PU2j|qX%j}3;@QpqnY_$9)iq5m>l!iIgdm1$&e)d5$Mx74o^Uss zfS}LFkQ&Vk-j97Pz{`4e>@z9;JYR>%x=8=_gkW>{J)g`@27EkQ3QxpDN9y%||Mo-T z5g}k?1KLW@9$J~G^#}!_T;=-`Ef@gMt^3$q#)xwk&J%w&X)8xSG18+3kJ{ImdxJ-_vpfAtyZ_I=J zz~KpM+7W(kz*|D-NGVNGCQHIo>d|M`*LF%jq~Spr%CD9be-nTFhBR2HYW#AQ{4FQt zA2%9*4Icj`9{j6YP>$G3jDr|d!J7u!vwIZV+pQW4PRewAX{-J zkAc!y*i(_l^QvIjNjimhwLA+gviK27uR4X#BWW28}Rr!e2_IS#w3Bw5RS=rj6DQEhb+ua>d-`gIyR@SZT_Z1vd zD;|eHKnR!7UQ!>`SDc5doQ#_&TXRUpXf!FJ96EnGBNMys3SJ>B5~SCgWJu|`Sq!mn z+8<3GR3`HbXd`tHJExB%uyRI3Q=(q+obNPH26qt(oq;b|19$^6yN{AVwqT zsPjs+7_a-C`?fS6@5WUt9U1{_4G}kMtrIi-q+VK2NK65LkKR0Wu{RJmo?oX7p4A2z!7 z-;d@gkcH%Z`}~#=%NvBbn|kVD(vEY3K&SKm1vmB(6cHSMNO5r z8@nLJLTk6xnc-K>mlsf&kLNkx^^K;YwW0|3A;>@VownEP7oq}5}v;|8{+YFU*W@8pga5HCSbO%(hWkJB=Vsux` zA$kOvji07H5F5dp+m&Eb88SQf2x2n!TzL0`-T_7D=S&u7#1DmT#hRVywTGu-zMgE}8{ z`<(bir1tpdn@WSEbr7HR$D;b@vQp{2I7+=t)&)1v39$iJAKz1~`J8Q(Buq{;bjPlP zu!rUXsx?=*Gk|sM2*{!XVIY-04q?65#sxZ|iaH5+Tgw~dut3ckcb@Vsw|2=CpFLCb z(-TMu@YGv0;<$!ugUX$lBuip-eXwVlqvRoTPEYyDQ+TDX3*UohwQaH&Ypc3m9Nd5M zBiXPvAlvI) ztG)IpZXkR9D{_o4B_`6xn0a=9&q1Bdka`3R<-+g^p5AelF{h0hi|oBi0SrcAP_~2+ zNC1B3M_r9Z>q+$l(eMQ1z}3UpVnH0(U@+(BBYe+fdVEg+8$nmC5eF6IhNB85litF7M#WaWPut?sIL>&u@?eZ2` z!6$&p&;yf(ywJ;|beFo#6WhapaU;UNG(tvfj5wn`=Fryj0ST8@6|KUMfId z^b+sWak_Cn4I41vavXoNc!PHtvMT*1*;+ueNG{s2BU3;l#y}g6L2uHd{A)yK`hjH2 zgr~FoG~n-C3xaN8MY;gkHm&XfBqC6+5@+%#g3zJ{d;&mk?pQV%M}bf9tPVMk0-eYm zxf~&7@mMc-D{YMKQ*VgB#Ax_@=+$q^%=F{VhHTTz`bAY z5X(X?>wrLOjvxmJ^5ET?B;nyD^T_~NY>8A#1DvZ=qim;=d=J^#BvJB?(E*w4TV&xg zDLWkZY|pV|r?#l(dGYwI2|g@x?YdQP>~wdWFS{iKzaeHrtvpRIeNq~r(qq(r@VfR^ zrR{|H4zZEeidTuNp(&WkCp6NY@!Rvpso1ye)TWZgv4b%uxEK13hx!gPchTT-_w@{T zfRkPzeXQPLJ0h(ooENG?mG{C|yUnh93u1wh@MgZ+KSE^xy>t5a^zmPP0uBFuxc!fg z#Q3lN^3VOpN5yX|k&cev*2(RWSNcA`03msPqailm7J+wk^yNH~o{l+c_XyBb2nw3Y z-77Qv@w^M=Rqj*@y|DO7!n}I4@RHV%PO$j9nWUZ5N$FIUjS^VqG>0(oStU!v;Uj{0 z1^x2}_aTpdymc+W``hh7^xOml5cIM4u)A6zb{EFO>5-|Dii&+I#>U-HR{^2Rjf zMFfnZLOBweZLIxz;vs_yxJRU#9y%)4MF@EzMZ=rzux+T_C|@}Zo>t4`ca%&ijD;pG z+OpmmQ!G<CX#NN6LqDV!s z@jyW?KZ78-B?JTKxsFvaCDK(D29Hc1P*5gg?al-mp$@ZOHbSL^?d8rn#A^MV@?3Y^ z1pKjF1e+s>E_wCMj)?DKQ%J;@OA#eXAy_UEdE|$g7${V9*Y3|35*eJd9YpJswUPDf z+ln8#+R6Zq=ndRd<;?bClRnWO-vnM%`*c}|xy4oY-gma|w_!BE-l^5zsOR?R?VYo0 zOj-E`;9+OhGxvtWcLvwI6_g~~k6N{=G#=+2L8Sh$fBE?J{KxW~pb`95A|$l~FR z+6{iukjK|ju>EcH%YW{P{~iSUy~X%zK>0sG+J5ya{{0ipUyS}2l-JIWJbq9FMu3&D zx$+ciRPo+E7I6%ihg}fLy$8z%La6gVt*Yl<(=%5xvX}3)!Bx~RuoA@fIrzAk)Y9>Ox`IXs z67lpA!O^k9xyBbPBrdTm=!j(`v?=JZ`cgwo^etfTB4nO~E#Gu@;Uz<6%dpF>g#ds% zIKcyM3)8)B>iJ5WzwI(oU0pajtJ{&ES&I9xg?sIZLAsU-l@^oxwa7dXooq}zc@kp2 z_3aG=EnxOVWt3aT!rckmC}Ap)jy%;QV+4_p;8)HbiBfvjK}pigo;aaxt}d9FxN3&< zbnNv9QQBT>4jM%qCA*g}OHPvgb+U=w7(fVQ;DJG=Es#75Em%Bdoszdm#%?h;`=H8T zswgYtn6U&eL9AP)aGy2Td4I7(bRR%fozeE7rCeE=?#1%1`-9+ROimi+gX#pR_7BxU zfV9G)vx85=%!kALZ7k*R2~8fwXU($@R6m@Ouc}miU>_~Pz`s`+WaHgFFn)Fj^oAk` z{+oopt)CW7xCHfAbLCH6Ikt5Dp%AvOt7=BL*su>A(4RP3F8B_elCD0{Kl!%0zPic` z`Fh2uWMrCcUi{JAg~`q>l{bSZGe|+6!x2Lwh3vdTKFif?QRXw(DQ4$BO1TPR?U(28 zwhg%lZ7@z)HC!*hHmTw+hL!yHm9HYHTKnG#uPJ`JJ{t0h!F=KG2JKWZrXaHQbjDC7 zS=(6<27|>_D92yacB>Sr^9WoNdByESJ&u z$udf3WJw2h@=qQ+I7>A+CRy>B!MwCF6Nhss(;lT$^|b}jx(5N@h??cqel2s$OI-;k z$CrZfDRS2?J0NH5RWzS?pyO{npwFRoMy%$3>?aUSQD4}{3>|G|j0y(y-+^)RxIo9JgjR-ighEij6oOm@X(bY6%zc2&-UKfO~Wt|E>XX8Eb zo*o3``{tHoQbdgUMX7w8qVm|Zxb8za!Z)dc&u*hS)BC1O0vx00C6h_x$X6nM!^9kx}i0l!8OZ#N8H*7 z9?SPZvk7dJYwAHdX&Ap?R2)=@K{eZiHLmU7w1;du*DH*5L$0uKV1Va>51e?KFPh6V zBQ1@sYLADe1xmjXm&?07Srj7XdVjyDF`52MlvTO2W-{WVPeY19A4r?M7^v_WZ5SsE zs-Cz{hl_^gD2;ciUK|Xaa_KL6)tBMnHrY+$2eSHF`7!R4@v|FvHODw%vjxqQLldpsc66fEOJt}5?4RqrA2k+zmWKl@OT$g4^ zpR6AU`_>e1kpwy+HH5AyvO!9!xq>?3wIX0@a5&9CwyJyFz-S;`2BGo!G;^N-QS|50wPv@F(Yd!su z-LOnSa9;|KOflEE$Iktg5wkIFg-b#)1~B?A!Dn#4M=lh!A#5+{qB&L{6&1LGc9_I# zr@ekb0l`%5Fn&*wUiVOsb6OVKW606AH~ohDpd_6)T>xEiEC4ZAtkWovvN!(3r~r7@ zQO=xw0=gA0;m2G2F9>1%`y_!=F7BI5RwFmlq7~<`#GFsUK`HL)^0wO^EB5`kwVe6L z=S75k2W83rXPp02d5-cV%)wn5+nDpi8Rx!p0UBcGZx{hBw!r%h(#LbUoj-m}C6H03 zm{rzDA1EduK2hl3dgMrN*Qxvk)na!GT(sBX(Gu5kGbvmFjL#e^;%sp!(M+Y;T ztf1gt&kR|GrS*A3(z{(@KrJql=T#{zx@)6eX~y;^^DwiCjW$#_#dz`g&(-)xU-E~b z@XuZRf9MZ?;gh-Fym{iH&BDJqL#gf$JB81jjaNQa>^AD;%w@ z#8b#VX)z~DMsHen-|?j+V^s)086u^@oeZ}wO_=)fGPla0!_#1shW)O`EUhD_#LYB- zxL7tT_7#G@vL#Bm=PpAVc=ST*=wO-sQS6gM`fc+;E|EpqAU#Z)+7-`Y#mIdl#Fvc+CcZ0lQv6J3@jRv~ z3#%>ot`hpTxn+%}hTFzGU}xhUnQl_+I*N-A1|D6x+%0?MNJ6&o$j#Q?%N(03aPK80 z@aH{PocB35s30bihEKtk8ZxZ|+ANy9x&jjer}AB(Xsh=D7Y>T}8=yRcDA&PKkimSd z!C(ejpGA!VITr*wq#cq1!ux`*#R8ipfS?>=-v)i^_+<6N`$S$=bi$O zmxknH+Sn8`6X_DG`(a!(yOw#-Stfn?)$7C;H0o|5m9X+i?X4>S_kd3oEoNrlDDK^3 z5$v^lS!m7It-|f@0GJ`hP zwLX|4%EucnAZCEnl3*}rcmW&KMCs;a30rZy@pA5O55zVmr}0Kv$R&tVZp+sZ&ZW1P z$YqjOTwgvcj&iZmXmV5W7+0T{SWGPdvgnV!KSih7S4b}(=R72Wpr|RU2|-Tj-@E}k=W{9wkJkhN-$xEU0RGUc)<;ak z;gR%{e751;=3t{IY?c|^&ec&AiD2giF$-q0IfIM0&TPO%)Jb2IL#8Gkz9R3w-NddC-FFeLhb{fd zknTvImd{UaSW-ihu^o9t!0dD0wHHKRDFKKc?5@xdeQbRK4K?v1hO$YJ#d__4WqC|j zNoN<#QGM!8k%cE8DZJ;#t)1J9vh+-pdu)Nwg$-<_X-^-EyNVdz^=V-_H9enR>s~^i zDtn%~USZz>6~u1wzZLy}VbtUQfI*G%Z4n2!ZD&6?L{o*Wb-paky3=HCM#ywPQA=H) ze%!fxVfhV*`>R}@_OXqh-V>5-IFhf`Ry$Pz&BFtU-Pm2jK}&nwZJzASuiEsAZjsKq z)`e4BeWbmoe33s1_8WW8Gg z?B!-lD^I$%L3tHG29z4R;*nMfI_ z+T^~vaOY-$thUoANwpY?Di^=bR?jtsmO=$y7!U(y!165AvsgkZnHZH}yG}~gHkdt! zF>vptw+|*!2F>-%b%MSWcSUc5VVXZ9%`#)Td0Jfx5y3*Tfwc4p=N&n4f*eggnfpD? zCYr>#_ij?jI7jr}!P^X@yJTEKGz}F^sS6EAzQnJu?b#^kGph#%AdE@N3!E&zls* zxyg}*+i-ic8iNOI9}!Zb0n{nW0E(QLfLJx_&pf#CpKA5=z46_cE#t>gS#vSZ&dCNo zi6cCxZ}@lVje+arEkkpuNp`A>+jyvUBVHdFrdD_g*uD|Ntad+%@`znit%(RU#sl&B zfh@k^0lIrAfi?d^F>8819Z)GQvKxaST}(fW^dY!1nd8G^pBv~4* zAmOyJRn90hRiB^x$&qS;^a5$i!Z}R~^<-@@0qA@so7RBY4vpKsC-w~;k-ke@r@EvqV}*O?5J(x4ZNna7P? zu~4$xrs3Hyb`5`{Tm8~H{m!HM`!V8o^yd$;@d)~NS|51hP+?SQ>+tN(;sY}1~f0#S-aH#*i|7Tw+#SGd+ zwn4O@Y-4O=XT}&6B5lf$H8S=kzP89-wy}gkS&}SS6JJ}15we>|W1q2w@OwMw+~;(* z`<(lCo%?tF{;EGTIBW#ER2%ma@mh1tjMu!SSgRkV}-PjNJFnaHf;<+(g zhjX~XF&Hy>Ll;~aFMqlGLUYLPZ*8;VTZu=F1T$ax>oqxZf{3#&PmLQ#*vV`WPto;H z+<%hiD-zyjpxP#`EsHq{1geJe1GkFu&ow1vN*RbK2*a*k`1E_Cx;WBEK}A24cPjL( zUa?768;li}JyXNh_cj6jZj7V{nrk4OO!yA$KVh8c6V^>`2`2DP-%*fY*uXDciW6)H z{G4|d@0bPi#0Uo#t>%oUu-ExV6}w+CehML*x~umxx6SD8X7 za$rQ1&MunMNsKReOuqMN-YCC}XZJox+VUshZLQIt+B4~MFlS?Ru0P^7cc2i=pEjCL z$HfWQkC!+ya0+L0YaM~ru;gBuRc4zFdGsU*@~OPU-hO-3Lniw{MR6G+_Q?vCPs)F>s7akrKvvt)jU?Qn@8+@B|k#`RTWWp-X9EK(WCV?>%-9zM}c` zJlw&#@t_RaZ`YBjyP;esXOOV-&7&jB2@2}&=i57o z6HaV0g0{c~s()ZxFS}ms@yaogw|d~extBFhFjIDcf%4-+u^UZXTlorI!gEaoH`r$7 zg~H}rCh86?AGgouVz~{|&&BcO95rT}l8KaNqrk12A;b>g9Alb)b_eA3?Ang=n%qna zc-RkkW~$U{TeF^M%~c~>^t&z+J5@FwO`ikl()2nu3C;FWmCih^xK}-bQV0lny(vb3)%cDD+af0@`AnCh_sk#2WRoP?HELYnmNVy{SkxiX$G9~`GZHP^- zN*4`R>MXaA!=2^M7lsAxi*XW! zk&LRysn9!|`g)e#y1jxsx1i|4L#85xf)Na7Uq-1;MbvugX-TD58g17$`ygTsYixOf zOrfW6xZs`-bj8DCFPYXXY}1X0DrWh5d`o5yn)84_-zzG(Bt3=kG=|A0--bG0rMoG) z!vVC4gX6Nhb=0Lh-g{f4E5nYv>vX$5PRow1kJHV6k~;Z|$Q1sfZgB7DR*a9*vKGiV zroUgM{(BekAFu9To*E!Xxbz?PPJk=u19TzoMN|K2g@D^ZHD zo0J}L`EJ0~Y!f||$@!Xc2(Fp*B%UXWm7E_-Y|r;+5BE1VWuE3#U{b%pO{Y281Xsmf z0Rpphi5sfc$2b#c#$R%9?vC<*NG0+lIb-{sW?s{*n$J3+WtO510VGjxmRLFg5(uOojcJt_2 z!L(f9kR;6~_Pf)s%9qfg27mXx4ncv!1#b0a2%9x5uL~G^Y3sNggz0U`zc^vA$h#yefx%{b}(KwjI zbeuKytsX2v)82eqFs>h9rt(e)#9PIRgrzcWwEuWr?`~&GOfPjqEldm++vT@R z0#*&6Fl|AX*SI^YZKbgOFKZM2VfFKGJv;HE96QaX<7@|?EUi}8^F%yRqA&_rmp*AD zGaG9Gr%CFXnWCB?2Jso^BtmBMh{wu@Sidk3CmN}OO@30~HKFugszlo**!Wp(Yw`SZ z=kX)tsr4+AnodKMEZqd+=xN}kGijH#J5KU!5>C4#7XVzRFAruwS!*f$-~PKM`# ztcg?DDvr4uODUo6LP83KLiqn$EDCXk<7ZD`1%6&$)S+|$LHz4#vFvAbH75tJ39yA`@0G9y@#qngmYoBM6L)*`1kyq~V8&W=7Yp=_+NBIt&MrLk zQ5#H85LDmIk+IcIu@d*8|D>We?AYthVWGXP$JE=q!>CMDe!6{b7AM7t-YV>0QV6KG z{_*?VxIayf&W~kwTse@2+g_l_1ui>k8Y+320cZbe`n6UfxW+I2$F6aZpK$3PDA<2- zh5mbIe7{UT>k#8S&tC^j5gg+y8%TI(rgz{cjF?yAiHBn2zBFRx9&klYVLjhqcOm9&S$!z zfvCOdqe{nwVFV$wFqRG@N!(rRy;xMVxjZp4`8H#pBv&{sKg>7q2|FdeJwtN9bIS?5 zFxp3wLRm(O zHLe^*G1FLr3vobQVa#0@p~fmKI}4^rJ=y@i*6&%+%NB|+B`v5UtY1R`sv40aMKk5F zQ(&U}j5cJlP`MiyUfgcsKdD&bn*eTlHcQh}2g3n{{x-Rz7i5o0X~H}E@#bqUAHl9o z2GQO>la}lNLJK&RcaaN<+FL7n%HrqQJ*N&I^OFGk2!Gv<>Q>8hi?ehBJ!hT=eu zF`W~A)PV&FE3Qw%Gf+5uOpZc(H4D z+xNKe==Yyr3hrd(ISCe>YH%appzK1ms1Bkaur6=y>@;gPsZbA=(HkZYh$7kJVta(D z`omirT%{lk53%RkVWGHlXH?})(aIE9T*3dpJMP4t_2MQn*?${qWV(c#8Q*!^{OyNZ zC9LK4h`sF5a*OeNEe;G>xO6^AFheXF=m~=6GAyDVCFc%KuRJGAmVvNd&URRQj*YSD zc>qyKuH&Ju{(gV4UY=scB02VRo^ z+B_>wEWNj!6=ng!$!q6uzsNhbV@9g?kQ{dy4_>8W>N7R=w{{I{lbTh2wm zv<@YF7Yc=`Z)TH2xk5m=tCkvO@j(2G9~ip6aM;+hz_3O(PJ?rNLBQe+YWsX|&l?7i zS2W!w-Z`S(vJu#NvELHFE{b`Fui{=11Y%OX1wS%G9}y5tZGU?pheRu$>l{c{SMYC5 ziar+UZQG1RDq;4^ARQ1OlF~sG1b!34`g<%?*>F!m9imOvEB0`F?;7F9L3f2&9EdGb z`JzmfGabN*&x#)o^*=7mG)_QvxSz&r#Gp0by^2LE;$K4PUWDSe=CzMRxkJX;b4iqy zuQHEKo2mmh7`hL2AH>*_Oq3E(Ag>3=GtY#>7M>2Rb1!HNM@RXr2dp1n?|G!9?EEeb zg0|x{)GyV|<3y`6uj;EFVpXvSNW`>hyqe&ArD}@{GA{W|deK+NIIVtT6kF?g1E>AiD|gu~Ea@pHwbAl1l`WeQFCBG#BHd#Lx4CUcP2ClW4FM8hHN~Tq zth*-)H4ms~rnvfS4YO66`syblM8*-vcRn}Ys@`+pL0g}pN+z>Y#mN}gKjb32)jhc^W8xx+SB;2r**D44OzyLdpDQz(A6Psu1dZdcJV zM@!Cd`Gi8Oo>1O5PVAWsaFVc_rFg+qUzRT>8xZ)+D2^Y4=J#IvCOz%2@*tC%*xi>$ zgz%)ROqc0 z>f7dxy6yF5&7*=nr~wtGg(J;t0}@$BI^XgYx_Zdx4O}YQIHH$kdA&S%{{eYO^7FIw zdD9B>>Q*mI=^Musy`9b-HyB55p?>T_vV&dC&!i7ICi-;?3~g@2`l*bLV}9Cy`r5Q6 z2QR1Hziw6bqkDjGyi~k0^C&<>5(Lt9IMMs;uZV-j>6Y>n|7!%Te^wd&tEUz?`}Z}; z=ZsV_@^teWigcklx{B5pAIk;<>V(b{SN2Sk1_bT(bGaz-M1gdtbF`SthWQ;m`cHxi zD3MM8_!)0#U6Nzq@^QeU9XD7`W~&c$C%;x8vw@IPw4?m3QS#yL5x-cprs}PCqXs}; z32PP9I^TSIa-vyNQge0sfM4PSN!7rxOa>S(+2DWL}f0lWqxPX#9Cq@m8TQ%pH36>GMTeId|<g{ld$XGNu`dmu1x6 z7J5w4Z=+3OGsw|ty))4<&aY#6w7;GyET=yGaA*yqyWef<=RPf3da(~620Q#{Ag4S0 zxXIM=`u8|J(0!DR{_oU5e`TxwmDcqyOsr*Krdg_+i62_{WMw+<{G+}YtXAxl_-ej8sYp6@738evvOQtVchH+@=c)v=Jk`bjyHt zaH2ZT4+j|kW*@m8*f$2$wxPuPuOc)-NgU>VyAQzK;L{GV+Ggt3RoS?g{tw9U%DET| zO5-$XS2)w951WXVp}VpkqdkedFj~|O2obyOe7PfTO%UE=*XWQq8MeGrKv)_nki2J` zwmeqD1HSOvS4A+ITQ%N<#^!4&b5nw(+4?HNiLQmf=2xT;hkhkDCl-5%CJrz!9|0rF zWeR&+lu+uOrOGa>jO6@bdQL{E_(8GG07!M{u5_&0uz*k7VQ${irv~NwqTtQ}&LDtA z+1c4S&80#TXqbSFJ4$E^$Fmuq(_41r_@x}qM22z1o;^?x0{JG`9!W?&3UKC>f}#p- zFtf5s4&o-EhXzebfXtF#8GkNK6BzUg&_S;UwlZM-YL$FSdkJ>5X>8=HqXhnsdzO2WKOLC7_GY-w4wQ7^URT6#` zzVpK_qPf5-?s}{W>csKgx(S-(;*GPawMLFH=!bRho^Ye2@*Vpn(hqF=uEVc>Vt@XY zT*P$mHu1t)?CiJMk=!+%fk4;5V_A6m&DsY`;vZ*47jWbE>%OXv`!J1bw!(f!X5wQV zxtG2AmlFNXZ*DwXmvbe*J9)a=RA302T@Qr0+cAzxav>MrIH0Ok&aF%#>+^KFc z%26!<)&d#8wc<&l;2>r`FsRU9BkmJJ4@5+3+>~k~2DQUb)o*BQTw;t+Yol)kPYtm7 zP!KX@k@T@cUD}dfn9OcuuIl>vZ4LlzK7EGsNtXwyRbS2zN9GQTh!KwM$fkI@qZCm% z_Z-@w?J9}E>LaI-y|78gz3&Ex^T_BV zfo_ANviQRe!|CtKH*Z(tx&Eqs_|s4a37|xOB-H&97_o15{Ri+ku+Cy{A}y&bKGT3t zYyM6>=w5G}18K-21D5CZnRJ0$>hj!Y;xr8tFQu$|80)2EL#4#v5D@!Q7z~=;@5?##+sBn{ zb5g;0_FF=|!~-4-REF0KVGLA_OpPSSoLcki?6$hxi{!AZyvWMH2gb*_dr+~=x8L#2 z)~h2Xlh3>|LJOt4tdhzuC<6PF=}JDUfEGVSRZX<%d;$epBgh;0bSnQLlq1Pl^e&dU zrBXEahjYNnz8m|Dq(9L9bpnG~-zBg%`vb`?)qCrw%POd;dNDje1x!$B$1X3bR9Nnb zYpYx5ew9c+x?sY?JyZN8VCly5W|GRNb3Zw~SC!=z5Bgq7pL!b?v?oiRYNB~4n(icv z6CJZ_=YglMbm7zP0o|v&r5SJEI!D;O@HLxcTn5pxx6I0}uFG3+vwzS#$ZOAkF?~VX z%dQWoo{#7vE-~2Cd;}OC@?{UG?Ov1CI`QhRXlgmYLF;94=NS~Jw|zd3H#L4TU+z+u@_ZnscSS_OLIMiZ%=h*EFN}zaJFBiA+v69G%j@N~N9Y;oL``P8XYp1L5en@5ea8MneF`Lt!hVb$Na*;#;mxTB2 zy|Pnkj7H3XELrS=tTeV#inoAEi`wMl@8Tmfr>bTQ5Nguglg*w+h}VcgvbPQ~`hGk> ziNbEkXe&FnkCu9qS5?wHulcQ=3;I;*|8A9mL2B#GJ6k{Yxtetn%u@I`@*x!Tz@Rj_Ln`h+;}rY?2`C^x;H^?L$< z^aXr5E&sSp+@qUCkKN{54yfqUpFI-)E~@9+vlpqp=F}<1*wW7FQ6HrYsUz1`A*%dU zt30p_6WXegvkXMm<&<^DrI3MV(&ZL$DuSPL^k4!@bLC+~S`k-WwWq=A=rwaNtd#xw zlxJXc`6M05cR5ln!SRw$_s^3?EWCkC7 z!p#FM_9teaTo!x4KMaHhC9U`{PrV;`uq2m_R7qfm;bhOFj}j^j&67yyg2A2>DNpdm z@=T6AOgY9l(G2O2M{a5Mz8yOVa#hShe3f(I{x0|a*w&MrJQ$K)ZSW%xq?V^|MT z9;U6MT&)E)beY+_L=z8+TjVw38JMoU2Vjii(~reM6rt+Kgsmz2#G834(~zh+Pqaw5 z-MRGk;Gj}z1<@;1MHIl%>>?aT0Xc3x`s z!7CbYLp$XJ$|Fs96;M=shn>3b9RyWHnizbD$j5uoxv+{wzsNK})Qa$&nt>{5DeX`O zP?5MtdjM+=X>J!zYY5I?x=+sM69aXWp!rp{XVK@7)_R=cLe$lxKs|P$Y31vi#y%aN z!~@+f_T>E4!_1*JGFy)q`Vj(!-dNn-;eiI<=WFP|7D-;8=mvpGkg6O8i)HRQuqhpS zWaQ?_?-?Tj0bYk_k@7Z~AirCY6ZYty>LKn_S(gWP9ygbi4=nV4C#Guw69j4E1d!O} zSLO%i>PD2hj4r-anwIsEniyNC7F(LzsNcDVMXRltNYm9-j9eS?iam-3ET#899lMUy zt$oV~zbOTxm)?&iSiJ_O%WXaOLeP?|0vV}!Q5y6qru#$S9{Cdk{p}M-RB5D2KS)D8jtoy zbuSlg?;J%95}zbZ0h&H{j1UfbSpa?O?3{AjmY#5Std??^Yr8egLxwG(y#l0CL50$s z5IL9}Wz;G6hEmt?^1xmW!p2B<7x3pIfaNL?eQ~ttk9+^xX$6+%cjznX31UQ%<6s&S zF4{`0>7-cfeeQ>RQ@r@>~Mr{I}@KB#k zChlEw;P)(e0st!N5F{Rj3$wo#atX21$bZs^U@{)jU&H{9l|xnrz}8BKhZBdQ@@Bl- zM<3L}*rnTnQ3s&I)e&l3wRu`F3>4@%5r#c_oyFvUBlpi4QbIFqoBJ)`*3Mu*SNO!! z76`RrVV>_6WUzf8h|9?<5KAk_D6o#mW>-s?j$_X=h0Lbb0G}^Q{g3`;e!tDBqi6u2 zvowK&wQxzODI22p$E_3dAA!restYT0{c0HO6L8G3@+MpeXcZO7t;(iLPe9N7F7pnd z%!|yP+yu%Gt&--42Hi_zeO6~ceGkGq66$cxapg(dGRDWliDpXJ>-QGUE`;Vk%E%tx z?O9>(Vd-^f1=A4_GxOMOQAzxB9D1RlCa@;9{_1O03L}mj6xYk1c0gLksdQhGKi_|! zX`!z=f!2oExjl~U+2m(WrXYKDx5FO_5$ck6l^|p`?DyM4mV$TV z)akAmZ8GjUob}~g+5wWQx&KAb|39hRe|^RLt^D$rCo=$$pN$5uPR2K^Dj2-}P{*DV zeUZib^^{Kaj77ixgimvEZ+Ot2#x4e;-O^l$`*GoV5k7$Ea#vzF z!{Gf3Z~8MCP;Mjr-msbJx!RfOlRQg4OvGVu2Rp}rWDAF0f+&_y3W(iR$DrF1DHFp*6)YaJr#rc-PFN?b|NqRXf_Ex(o6 zWPt$NewRF0x-40@x#z(xwEvea$yb2-fg!*Hf);J(m&ZY7OsrYA%k~ z-O1)g3(U4ZguLxy>bz6Enr2T59jh3-zD_+D8?EyrG4+8hxawCU%Sns=VBA!>IUO-q z)P(`$EQ#mlVyWgpLMih&8h!n02ke)E<{!GG$`Ad?3jWU<%fE-?{!*a-vohx|D&v3p z!GG2qgI7rwnQb2bsowIz*hZTh##todIa`8Wypmbpls8iEEm<`BPJ(W@9?|>A4W-A@ zE&R)6N3T4IH)hkM2F-ocePL}Dxm4R<7!V6K11mtCqj13Z%b4LK0FmG(czFgyMmL0)_}hzB_wXzL+9 zFyIG_+~>9%$@_RM@z=uXi0v(T2NH-h971_0=!N5+rF!*|J1LGwvocC@Npkh8<;@jc zDjqmB=b{BhAXmyPwZToXGwDa@!GL2NWY~r%k=gR_ncke6jJ_@#Fdmhv8OXj}XZck_ z%ekLVJ7tw9EN2M@O4p4@n*#NMb8qz7 zFuY;{grZPC?dc`EvxEjd5wM)jjy6!-ml+9W=_#;Gk%0faJ^|J6%k}uHDE`0doERyF zKmGMDQ^r5mFn&fznC zB~n3ny*?NDBiUZpsPRR-1HL_9d0?l{V$f&O69>F*Phq)@;?aVHRs*=mkT^chyFHL~ zd&|y!MA7_svn%)2L6#-oFPxlfO_WDqv43aBt=fRos94F?x&LI;MeHIH!QI9fM$$sw z;-4{|H{mo1;v%+SPGeSY9=zC`Cz9HdC+u(^JJ()yCPOs_T?0#s09}Ee5`MJ&#w%>3 zcL7Ztla($OA{J_bz^G!xFefml0H>i>SA-kc&$I+&U7m;AU)EdzE8t{pgf$SWnLT{i zN*w3{16Tu+`d3wgbl2P}JsU3Z zl^+@$njE4VI9yrx;V^^4yc5YkMQKEOqMxJUaAoZWK8D44rvd+Jr4gBlF}e-6O1}mM zzS9O^5)=5(ytscHGX7h>MWEIVP*V1Fo*F}2oT?gtXj~5VZoDck%^v%k@o$1*c{Krj z`GUkYhE%;4R+t_^;*DNas9t0FsTU(`b3RQ_wc}&3EP?2zzVm+Jw30) zpu?U!479?u5I$Q{XsZd{MVBc^*7MTJ&H1*t2U*btWN}VPzGQYhdj^g@6_`HIgT>Y_ zyu)rZD!BM^BcUi{6E-ql&j_w*sb32QbZ65|i(PAV5g^57Uw%f^Rqf0jb(@0lvW7gk z?F#KM@wifSQ8(Y(nfqX@hGLtEl6A7nMtdke3(vl3!l(^?VQI}9hUs^WK|bC%!;H^F zqjoUfbNL`xLg>RF3&2NiP;sXW8%d*+Fu$vc9J)jRsNDGwU3h@3fEOzWrmgUKAVxU4 z>8c;&Q;}Pz4P4p}0MCO(54UZ6@^DewoAr24yKD$^k(&U4`I~(Idru^{$OWU^*7u0q z6Erw0QB{!8U~nNP;NhrfA`P+zmuY?UcqKV;9do46JpnagCun}I)#YA-xA{ZYm{064 zLL%&|jJ^`MkTHjy2aHwV`EASPYWX2(-uWdkETvu;ycHN?8>$nn|}Zt-Is$HnbM zlgxYFu3GwC+3HnhER1Vh(yiwYT;d!D;L@LIz4gUEleX@&Bt21_zsTdhcw+VK3#2 z88&3~udmmEV=v5@*{IKG$bfdQ9rmy)ZaP6r&N{bL=3}AwXbFH{v&qA7`XD%vL(-XMVF1{m!NHnLBAfuHX;$71KwOuyag3UQA{QR zw0vvP0)gZLr}j#_0IZelQ_t|X1TND#peSGmuL=TUr=O_3%Ej0xoGE=&L4qLQBH&um zEvuI%`6wJ|?19`A?iFkAr){2!uOPSY1AHUn!#zc8eUxbVk)Gz}PBpA~k9wTXrgNR> z%%-tYB#5TJHHKNw-JY7zI3HQo(ecjcO>=V!?h&>Ls|5htPrIdE)l|BbY-tqrESn@Yi%S7AWG*d_!DfgULsbCSG%8FXkXGx>SX-HL zn>~#f)Pp0#M;{N!>M*@hVJ=iWx^#HaZRi9b3UPF4Dk*%9qUGy}9B1veVQJ5)$;Eg( z-z;Kq;468-@n$R0vp_P_$%U*Nj8*2ze33Vg*<3kK*Jo+{sXT+67ozm6ZzIkbyw^_wrVN11|JHL=*l``d30z%h z>;si2_DQz~kV^TkSpbq(ZB32Ofn=Blt{Mddef2>0#S@L<@0PwYrj&_NO?Y@(pw&6J zNBRI$#$%o1N`D`1!nyM0koA*ZV7kRM%)rd4vZ0>lJm`inB9e0bRTB5Xh>8Wr?F04> z!~NydIZCRHRiiG9@94vZA&w?5hV83x@o2QodFDze2tk0D=H0<(m9CMoRf2?>4e$yvJgZb3ZWC>k}yZr5j-#D~61_y7E{5zQq z-VB$adC+IlPAFif4Fl~2-Xd3x57N|mxSjjh1>0U)t4hec)VR%sL>Ap?P{7P^(-#`I zuk1eHpG5~~0aW>F;9(G1SmV6W9Jcms@psbVvCT5u_f%cQX?qZ}EEp0m;?WmhxTz`s z*+uVRmy(qy9spZFwsG+9RSo!q#E~ON9>Ww zrckj^;!8xVP>L8qAo-L&Ct6efR>xY}^2<(;%7||=}YWzT4>3v<@Z$7b!Tzb)~jT@Kit*eh#Tl1`0Ke03! z>ctB0S1gnKoKH8-CB#Xs2;Dw_NqN~s;)}z#XV*^(>`3kLSKKq-T-_U?O@f%<1eEX; zcFX;-Mc*Wu?wM<)YlAi4IesV2kh3fnpC@PO23!ZFZ`y^}u~^7WY;njPs(k&ykilWm zsl)%e(#YkBbq@DKm2W;+GAu4Sb^CjZPQ#&GCLW@xX)G@Ir{{NwN2)j^!HDq&NLDc|=|#gnc`W^4VfV*LT4o`O!5-=z#Yu z$XwG^eGB!7@3=HA{wzrHZLjYaiPmCr{;QQB%A=!bepxbG4~pMswC4<=fjH*eutpYr zB$XHV#^PZ*_PqLPibl?P=7p&8OA9t?h~dC37lD@y6N;bCf4>R0VV;*#rb0tq^Lp9h z-=F{VzGTr|cR*Ev?}7IA-H5XC!>_DZV-D81((7lnO-ywig*^>DTkP6(3)*iU^xUqP zq5BoLc5->)vNxQ;C***&F{lcBVA@O5p_R(hH9q<4 z-<*(N3ebOJXY%KH#eY9RE6d8)6p8zq!SOFYl8pOs1D!Vqw;$Qo4QLl_KdIWL5jAYZ zh>E!^qj&n#iaJ-oQSG=xz0yfFrV5i)SA@AuRicT9W5tzc-$2{qCj)1s^l6mnG@fpi z+s}@o&ySQ0lSNW!WlCBq7zCxSI?iGhn*eMI;XdI+AXRl$!L*Bge38*x>ZW2ztX)5T zUO{qy6M=-+N@#;X8*o6QQT$#z!i1x1t09gEU!KiAc2WPb%Yy7+P^qNAjysnS+Acb; z{l#Uz3F5oMu^q3GOyo2;lh*6pnxh4O?QkZ2DitgY22!Ttv=EmtXui#<=WRfQ7wXhY zc^Ivu^MOZ@4L7KT#0~+&{0%~{_)0w z5-AY$^*Waka>@+4-ev|+h3+)HeUjKj;y<^`$&i$Zr%z8>F=~RCiW5{%1lh-d$*|)7 zZV(Vrt?Aa-Gol9%dF5e0$hX_}DF+e!gOj`HaT7|Dvr&D)%l#Do8N2s*>xQZaZ^!oLj$>_pVlkIQd*X&0Ws7fC znX6_dG#9aUJ-@}u!oqLot7uP?4Kh%6zfI=;(s!z&F-!n(Yhby~ierzcvVVT%{|P1f zHxDsDl=JYZ~3w*heLzQ?kbcucq)T^L;&-m2hEXq63*?&moLLZ; z4g%GY67$by#pPETxjyH_qG(UZS>BDC(dcf3D^W5%YQ&z}Yv?6;quisL!n>q6w~x`s zE{Sf+&J?N!#i~!rCUkFKvH}T&*r!*)RvFGsjkkFL>;^tRBU>bQCk$IOr?5YV(vn<4 z>=A?+(7=0fDv1<`^;@yON9Kl#8H0@ADKH`xSeTLCyf%+NuO)M_6qkdSm@f0JaZf~t z#dv#mdki5PS1-nae|)S5G=w`x4^M{YtYqBgIXgn4HHoEBNO z8f{e36QmdVq1#=W9(x;w1tqDij7HGEAwmap-hF;0k%y z@FUjSR`@W6lHI7)92bWkmLxQk;@K|@e!cW*J!ic%GM}&LFyq4Alk(sD0_J-&5Ql5P z@QVIJC`_Q2jy{Y1We`U+-$F)}=E{YM{zt}KH|yhx~EF;y27l7Cm%~YW9OxY`C1BQOnll)bxgzKe#O|2 z;fVUJe%+kZ_}2qB=$0}!z9OFLDkpl;t?=!v$&FP?rpDXzpgs2dz?lt&wG%}sO-wBZ z{XFcqmcJu2z0v*A2yA(h?gE@S4xG!oLW(D z%H%_g5D6)_2+6rl ze3)I+DlF0j-S~>H`bjyDklc?;GpUwAf2_Ba18K5wdk*Sq&p`Jy35HfY*8$A#NjUdG zRHL{I8$r;W>r5~zEi2+%C_Z-QD!eloJC-#vqj{O?dtieluj5M&%Df^ko%Lm&zL#Sw z5JmOH0m~$)r9xq-!fHw1d=N(vej`w)y+>anMcVWY8)-%$5m+0jt_v+z#{=1o*_|-d zlMzt*Cy&}mGl@A|zPgbv`Mpz*E19zh1>RiL_}#H+u%%9H9_aS!=p~aS(nYCdS2tHF zHI}g#Ggy-@g%O)7B42G10n|V?7L5m#SoQxlzJFeVrm(`9BNz!1q$d zxmy08Xh{D;OaGf%oK7(M8T-Ft*ydN;lEV(D{TEOgWp7x)J0vgsNVp4a6O?EZS#B#i{nY*`)%pq-DvkEe z0gAR#w0-ss8A`lEHc<*E7K>1j)Sztg6HnvK)dloC|1^onQG#>-xQR4S7vW4`GC6~f z^$&z{wUM|nz~Pe2+dhTmQmcZ0zT^yeFt0^xM|>2v6c zlhNqSHaEQOs2mwG#}3lTgK!UdYN0RE#8M3uF=9-M<)vbom1s3SJ(#`(AuDaG3F5Kb zm}qX0glBI7WTc01zVsZD)V28mxbqjH0Rs5U3@adXm)xlF-&>Dyg2Y?;4nd%-WymL< z5_@1lWjvP*3I6L z-UT9zTUiW~fuGzDmCU`D-uP^t7qS6eqH9)7#|wVfkV>&--z*zxfxyot$ey^PBQL&K z<*DkY93yL8u))@IM{7;42t#F@?Z)m(_NQZ_*FXEU1om;LR5PJ`l&z@BllSw^p_d;r z&2|eRA{q;-$Bhgn!A# zH-_O$b*bRsgWe9*I$+cBKlKSIr_&m4+()QrDT*9bzDrLO zay9>Q2ZLst|8Q~JVIUGuyQxl7Uu?a+{(=C0&lprppGs`|@vz`KhNnbuU_EE5U51TE z3$u&OYxt~7MGy~6b4LYxE4mJtnIUQ&mkLvk%qxvE#*6Ty*;>EK*4V#z;<@pN=WsIx ze}eOhK?eiN(kE}Yq*=(+cX4hL!F5)1hWA5lDAV8Hp|j?eb*3 zWh-W=VuiS3yx%Ciq*tJU9AmNc8l1bgOPVfG!dc#k0#3R)n1JaDC6z>p<%zxEDwhIQ z0qn=&`0Ti_oU0Pnl=yzTiwVtG_2zx%(a%!!CA7sZ4ubx;l1*A@-K(Jh_@ZE1|1~(~ zW~PE9tX>o)_`^KlaObi!%Uz#Yw&vQi^CxQ1H;p%& zx^;Fuj5+%@6bk41{07veDW1UtH>f^r=_$9b$8=xaInF3Z7|Da3o-4P+q-u+`zg%BC zHHHX8^bZ{NpF`JOWr9<)Y5C@Rlp&eq`pOkCh>;IXTnmu^ibYtOKP)AFj%E2@AJ0FZ zB;AY%1M2rr|xenK<6| zyxvSa)!-X4lcbma$f}69ePetq#o^kyfN)swwpsmARO;<#U1+@Tx^^=pO1rwyHM}>p zDm7l3CXT9oY(oRB7ynZQ`3xEeA&UCK(t}<}xr1edx~RS-EoTLV_ZUfwoY&N((-Duu z>Ka+=t`UR@1_%*_9AVBY2gM)6S#WH+ekXrBs6GDxgNE_dUSF9OCPdHd?>BCf<_!>l zQu_dczBo%sMVH5*MKg}keTJpSPGK(IB~93Fny}_w-72FI_i+!e#>@HJW@1YLf6ph} z?F(!{+s6S&F{ZHLzIvoZ^Gzrd6cpcI)Zo)LM8~T=C-3Q{mC0--y*M2JADV3?a#EWHf(J5oG%fi;CDsHkA0dYw zs!@9UkdxlWNC4kQZi_?z{`Peg$8TXEIcG!BO=T?Z-ML-VmN|9E!vUQkrZ6k6n}UG1 zVZZ9WI2`7VI#RsHx14P+xONnoSEO%L@AGB9H z0WPNOn2>2tdNV|Gp4h4MX6$F?Il&pyt?I7Jo33T8#5?P0j{A(kD6jjmXu4N2g0nwL zqDqe)54Pqq(M5e`>$sxIjWK2q#+nX@NwA9{mD8MlpgNyLjWka|XmDH~BrXC(U9`a< zAloHCGTj)AJ3#z#Iz3c59xmZ&L6;D8L?{YQ#~tS8bZF?+LpkwyAcQ!+=4%B{(CylO zL6BcSO=F{c^?KWyNY|nsG?V1qk}dTlPJ_Yn9Zqy1Ui!809Ms5vJNj{379l*8xUTDF z2G4h8hr3R;-0>JXVwB$U5`UYYo$C6980l!aLHqV`I^{$<$M)`}LvWoHn^+XVyB*}( zCZM!L(hRx|Xn)G{2D(+X_!eO@&Ijy-@bt$9F^U0t@Ty|{t*5(5uI!IBHJDSvIc~f8 z+nX>fdpg~SpgV$;QahFJN)OQ`GH$g66mx_pY`J|ltu1Nt3fuUtWzsRIUdc*kJjC0V z6Xx^Wn>O`if{kzj&10`q^YFx=wsF$N35%i#1F+5(CWoaz+j9EtMq8SdwkTe2tkF6;c$6BsBIV%GjA9>x{-SNRce9NL;o{%94E> zTgWmZS$jY3>$&f{>v^u{zMtRwKEL<>$=3NjzsGqT$9bGLgV*n98{d9IR>~UQw{PLj zIZTA8`%92tH~3v?$;Z^`ee5phAUEwftf$2EaxqIcO(Oip=_>VI?qZ_+kYI|j$s=48 zV$uifWnTJu!jwkx%xG$$)ps2E14_7ne)^Xn!c30$zpKXrBW%pyK}mu$12_6_@W(GL z`>$b!pvCb&P)#!EzO7F$zU}R?*hNC+r?3{r$hksoB%e1+`UgEHvt&)oB5l^t(2(p>2Ev)A&TEZZ0kPYHbz%o?d<4| zyY9iTLMB0#{nZg*&rxfY$iFt;ghb0KfvRNTb`qe+w zd+nO&lNh9JE!Gj65K(0_ku=d2(l{0z_1QYBl*IRmt)Np7QlO(|Miji)Wwgg{yVMiM z-Bh2kt=;ke_FmA=CGZ83g?VLc7P`4jzb_=WFOL2tyVY*U)8pGYAoGCRt{;K*nRX7D z%Qhwe#o4VFOh(Vzy6LMY=-F?`VUjo`U+z4Y3&_z$>sTY)xZl!(;DE!DkGQY9EH?HOsJ?j=O#?rBM~oPW#nP$3dw`KD43PC(SO$&Xab z7k_MfaxQN|M8`y5PeSF#o?Ve`He1$v1t=3O(mvIqv*herZQc!gufl+$1u>Jz?XH{% z#3egP3SP&cH;m4eSde7)1TU4=joO9#@QsuM|G_9!ooV{_K=;4&Oj7`;0dU5t`uz8x z_ZOJmK`*HNH;5WMH~$*4lmn>#x8nZ_KkxC|w{)ASw=d(-mpJxYJG3h_<-KhT<)o<4 ztT-*tPL$5kJCVGN3gXbGr2gz0tAeCh>?oU=eP@!f;v)~S-s?VK#u2rPQksm?I-;z( zHUIHWV7aC*p^^5sG8P7sV0Ag=sinc-C?LjCiZWAh7h?e2dTTPxk* zR-87(X@vkb@IO$7)S3Xh2bLdtH2nR7fgYyqfaT|V=y;BNf^SLdNxY8fi9|l(bZ;7P zyPT{iA|wSGBemN0aC{Zs(_KuQ@Q+c?sdt?$otWH+(EM?$=zeC>|K3 z&2cQh5v!fzUOe_t@9xq|nes;FSCod=Qy8na>zCGkgmtTb3ds7Beh(bl1deB$1M#j( zyT9PH3{N;FdakefHFn?8Nt_@8n6Umw(Sb9?zwJB)zm%+ED)L_!xY-|%z#lbf$ne~f zi)o04RfyV8GCem=(W%LRP4XPM750R^$2V+^Raw}6l&L?uWR9snreuprJG#Uvte*9& zMlG84E3#IF^{ZB`8|zoyT5;B|nzgp9$|Cj)%->O8RTnIb>fk+lF_z3lCcOf=9k$a7 z_%P_Vu?~iO-uEFn$p&ld^AF6M`4yVvb~QDhRLZ(w-xW!-(#L2C`lObsxjZ^gjZkeO z&A0@(bx(k)-^Wf_`%B~S^SZHU(0vWY!KkRPUXTo(>BJ%wG=1(y1~-3#4wXBx4Azai z0y7+0_pWeV2l{AtN5X40T2;{MWQ#;k2icw0F~_|ogMqGFfhdPkg}c_eO=a3}%QNF} z%V}wYeE1fQOENS7IjQ~V?S-2wX8D%GQrYd>6%w&{v#GPwT`;gbDNv8q9E?T1KNx4e zA63U+4-YoH5(@};bA6wVxxT9@YMZxiX_l|`UzFCnaQn(PUZv`R%>c<3S_$AJp~qEy zpuAy4*0aTT$nT-?RZq= zGv2R5SIA00gFowH9X3k{lA|Q%OeY=Z;j=idnAzANv;s<<7(v_gHJ~uB6PT~)WYyJ_ ziF>jf$T-W|ccmtiebicA0mTWXN+Mc691i=$goK^MgsA`MJNm;*R)DiO>GUnh)>Y=9 ztJ`zW>V{coop=M3))Ur`+*i8BPj*y4@A}9}Q2Yg5%>|2AL-6BJWCMi;+g$oi zm=<0Xo$Zpo@L-l%CrB>f;qvS7whL2!!t%PrrQV4^@ddI8YGvk5?=!+1i4BL>^5+b! zKk3C+K|kCUwVj4f^{O*)D7grl3`O-uo6|NFhp$x+1ACp@IyJt{)q^YL8BU@t5>K?= zSc?aqu8D*_l^D4Xa}yoOgSm;1B*WaqMk-)udE7TRAG5!>8m4XX;zsamlNZ;6yQGUm zMuuRYdEAFNS9up}IC*&%KXUT&E;e$;#V+m(zM6+*`P5+~~+{9qxQHT|%%_eoF*R z>mXhs7AN3EXs8=Ysz8%0!u=D+u5LUNU7B7ToEpyu^_7TMT`RK#uo$U{o%dMA@?+|k zUti%CkLXy$nLfJ&JZ2r&dHbKOy)n|66QH<1$fsSE>BgEJnI|ADRK>H&z$-j~J+L-z zq~}#{sT5es#Ls023zPjmDy;lTsIR;t*T&|sbh^}h)yx~LAe7;@8s1{pIY1)g&YjLy zj#Xr^@vRt6=Ma8Not^f+F?G*-lM=WPHrZBFZdZ~|t44uCByKSN zDsxn*fo97*a*+S!%wApn{^;OPe5gY+4s0gbCEN;Jm}teWO7(%`8%>CF z$TLgM=E#>ANXof1|Dcp4XzFZlroGAjeUfyp zG3(7!?DTkxKB0=+$j@i^I`i?0GIf!#WeW3#j^WmY8w|CyDK3qLJKLf;ZIOYoiz3Q( zyY;fo){CxL`2<|jt$6ylU-?dcf9XO((U>;If0ZqeCuVt#twK-qVfDlIs;JKLZy_Jq zTS%|wsK`f-MiQ*@kE?HRKLraJT!!i=)xe>R&p)M^d~mxF`lE(wyrj=3WpLvMzHc}z zO@EiC{FB`K*ZATeRA9bS;a?-`f0X9VM}H~gR3S+4FSx{Czuo^7VsRl17^GdDB5jpl zXlWN@3NF{GB4k!gH$+h3Ug-YE(y24D;9>*(S%89p%TN7iybI`>rlEX=*~y$T*q1ul znoM&?e9iiptku23uoeQADZY1qh{yW3H-eqN+A?kK{FLZ7BumZd7sh&LSeof zEEl7+eCS-7$K7=e4eIOYAnspFmcdr#-P&RfMpG7{x#c4u_G1McpIkB0Ig}ZSXPLSs z$zV%#PdkqUk(a0F1@Vv$ouGPXRqxQJ1>chVFTunkssU=yaH#B~9hN#Y#>Tt5y zaLh`R^$)3hWaoJE_4MGms_Q=0o$rU6x5>_g>f^&Evvz|IW;O#XYw^_If;$Uj+CYom zdgf95QxFJ(`+$tvxzORlHvP}bcHy+>a_j|m{*tcFP5v`@`A04P37!AKd6)`7O6tzYYtbbWoX0p)j@N!=o{TV1D97}--R!?!M^Xm z+{Ed}TN3wP<<77Gj4^I>^ik2o6Kmaq;C9u^bcNvcqYKz`x(dou%i7d-0@QL3KVx2r z^}ZP*Sr{(x`F0VPvN&bcBsHhK06Fv!!!f7!T(fpZEi4Z<<2TEus4ajxRNYm~Z#nQ; z)fk8w&VEt8>t7#5fq`;V+xjVBkFSiw6JxIS*(gyw`)tnX9-Zna@#mHSSJYfg4HC`@ zm9H@MDde8*w;fbzbdB;a<;(Cb>7dlkQq7{&#C+r{)GO8Bc>5-z-}u z)}s!tfgt49v?_dhA$#EGH4<70d%*V%DobrIkLuK|TRN>32UF!UC6fZBW);aLYNG<5 zZ}f&CILl|B_+Qav+XwRe@n#MT(hnRS0tf^p1o3iI-EM73zxcH01c*nbsFU#A(F7V; z-qnzCJ|;)5$-=YjGm?V=Ok$`J6G>yLgNF&)-Aj7#YG7fnaEw|>(IZbP=~;+_hKWuI z&a>wCG0whDFJlFaR)Q{Lyooc5&T=o1oE;c*z7(q0<)0ZjzIe+ysC)75d;Wz(>t`}9 ze$ZyGi$XZ5CXKAMYftcu;Z))+O>Vm^9O)2Ph5EP9kclU z(NSh`k(vu2vRgtG+65uUm!;LsG=V2|5xHme>vOqf-+wP(OnG(*lO+HRddzFz ztn6)t`TZ^i-1=gm5+msVXB()T+c`sPpgZ@`UycB>#Cl1uNef&c0-kASJ>Bb$t`Rur zGnD%V(p+zn!O3Q=OJ$i0Yw}0VhMLKm7F}?v_wLCP#hwNruPn$42!l8TuZalR>h9LG zNvgX637$VqEyp^?pGAlVfA*Gir~e|V=G zE7o=7R_&Y{wPl^L|9Gy2;#-rF5F+<6M7mD~=qg`}o2F`Cx$V}N!by{nBFwl;Uv9W_ zO?A17WwCA^T0HUFjqzcDVy>VlDlaPj%gYDB4h*&!I*J?vi=c^qlG!@<;xP2=alw#8 zVm5I?jJ=m(+&U(NpL@m4J$}7{9P zyL)sCVi)dtee>4h5!gEIzYFgjtAC-etd)0 zZ6qQ{jQ&`nzOPaJnnTda`SzYzlw9I$-TA0oKl^K@u!G z#KzEp`i^~)z)e*@-tjQDFIRK=%b>>)t=QlFaLX2n;%&lwW+EUhE%*w{k~-{VqHN;L zQx}-a-g(cAT^W?mlrIO1fTqqbn-PK#6Lwa)U18$ZtEKT(_3n)Ip~=3(5}yVZ%d;)` zQr)>NH4g6F(<{fTPKV`;FvobZ^u(h8Z1Sss534 z@Nu~;mfLBWJCl-fGin_EIXlH{vE7#H*!|NFQ$QY{ z?>HS&i?dlm5z*B@2iw$w{JW;eBH+w5HW3ZBbK?1rmjkd2gqbA;Lf#4t`XXJAJ(wB1 zhbM$b?wE5HS6~Wz^wmXCt&er;?1Qgb?{o&#yfhb(;bx3C(k>Xv3+zKC7uSEl@HP`V z5B}(msQA;%Wbym zjS7p)PnoPzf1u9wO$Z&0M18h)>qn_O7OEzp^j8Hpi1^x0?a44L{8VbI-`#ZAB`(PY zK!|{g%-{t^IL$2|G$YoNXE;vel7~U%{;CWC{m|PnzRgPt7BBAspR(3kz-#Lvgx}2I zGmL&_th_uC^1HYUm%#~Po(31n;#gRw;ZGu5LiAm_VO?Rq;Wde4lIeY8hWgBAc`|7) zo;X(Fed8uPOWEis5Q6Hwb}p_|o;FMLyrLo}!%UN53E%ma!1IwA&nF7yT+M+;T$$;K z#T#h<{C58=@}$A-G%*jYlLpRK42`$I0nfC=fw4T=r(nPkn6LuW%51!qYi7s$DsRbn z4nB2D)1SSze#YM(+!gEH933?2^F$hIpVZP(Y@aT8tb0A-;#(i`{ko2P|H7OO_I;3k z4)!3x!kPR}@%*FX1h8}N#JW`^Yk6|N^2}vbB70gqTHyTg_#>I6meuTYUH$RuT9*%f z$gBzWk)J6Lg4Mx=@rSgSB=+Y&=NUTnM()kNo(I)pvlzAI%v*b)5Ax)ZUSY=i{K?T} zUU;KiE~FK*Y0XL5YX&@L)5DmipsAHCX%bFjM?_B!;K>bIUuzqVTg*JTxgEdxN*~&= z?HB1C=9sx%@MX1f{`%f^8#|@i^2hOJYn2BRzFX7X<11e3wb06*P`NPZdhZ`wm^HOS z=r5*lK-~9C*OaI$SIqTPBOyeE=_QRIO-Wgl>uhBGb zsjcBmba#d_sY2kIrcf43rk!j7LWAVE)ZFHrXCX?l9 zLdMd&PRCW2Dw7RfgCvg8 zuxYRJlbh&DWBEsFbcHD|?#mkwTB?OBT?=g@efbMIn{(weOT)Oo1m65MNnzd1BP^L2 zn5JLaEB}V-`G+sWc6)k~_vw%5x8jDbTaI|KAg>mMT)f8w(Uf-G9Jz~Jm;>*z^dYko zqd@$@h(@#co@L3%o05$uuk1hKA!*IKC!{>w@eB`=QRhLfyw8f+qe`}aRyrY$2o18?k0<@S z9znB3kt|a?nJK)*$dU3ht3-<57U1vRFT@AxEzPn>&&}Qz>7~qulpMZA^U{$k-u?Bu z#EO?e9X8oaP#zl+=48DcyI2`EYdEX48BlwxYsvlAt1Dr%953v{4sg714ol~F;TU$2 zip2>mYa9Ev)}C*@z|r*vP;f3Uj%{bQX0l0Mb+AH(0)i;FArAD z*#me1P}0sAG#~oGyjFh>ya@v_qu*-#Hk}ResmKYwvW<|DIJY*A;m)^T6S$*OP6rl` z{qYbADPm&6?A5$+w{2F4`?g2=cVkalfe*TGt@c7-TJ)B7-)5#a2=pyeq1@?#yd zIOO1+d4^oZ=Mj|q?{S{nCO3adTw?T2#y#D<8SQBXJ==JkPA5)iwC+s+otgj@f1{GA z(Jr)pjBWvrPI`3#+3VfY=FF>A9(ynR0&*1A7Y_};xz=%33!GOTFI<1V5OTN&zLqDt zq9#w)mnDC;1{+jd$V_@u4*W%#Q9V4L!;b`2)LlNhcfW;-X2bP%2Jtc|Xe7@{Fe%{U zcIV|0+ZI}EG@m_YjHh`QPbrrz$0|m2WFa^7J!inuhwHV|S`yIjJDvIb$skxOuKIqO zZ=~4A)!iVv{li4g_C=07MY8Y2?*gM!_Jw#?S9u1TR`KDaF4w#9T4$k|r5C=_7=N0Q zyH0*Fd~|><<(=u{{l?^ zpZfV+KHF`b2~=3YdK8`Pk2Uf(ZWn=XLWNMX*w6y z!WwDHw)^BoMFalMxrnAK3aUQ{xRfCa{&-q}aM>WPz!bk++S zaOnfD_48|eGSYunUe~S*(?CMp<@w46tr&PV!-GSTd^2sZG8G8!S8p#6 zg1~?X&@oGp=W2pn=8<|H{yFIB+8Yb7{}t-F-u=;7iJa)~aYx4j`~)rx@T=z#5oE2U zf<$yqGBhg%yjldHK*C?DsmjG@aN=O&;W73ox#O&%QS)FC+l|}w7m@6x2#>efM&dnzp7n)EXlcFr3bO%JNrF}V}0Fa zcDhd=Z^6|qx~g5fjo#L`&~`$@&xNkxXx<7*DKeepzIiQkXw!Yd{^@_R zk^TyW|D=2WQoX-2$o~!B{L82RmumgjZwgkJQnXBZ4Z(%6<0;fir_ZzL_4dvkE0a~9 zr~p+M^ zz96AGaREgeO!}MO&)RJFH~iQpNRSs!z)&DNTmK-XFrRio zAC_!%@C-M2q=J>mLxY#Rn(bScibZ>ie#~HE@xFGk_+|_g?r#P|qmUpZ*e4^!bRdj~ zqVcAK?Qc4K6wno?<;a0$^t#EzZcGU4I&8+ZDFUs`4FfqQ-cGW-wCbU=mw*`favjuc zfvCQx6#26;gKb+OgSA~jH}x?3dCMoX5t(L&EC5mVaM{lL5x)C@vfeD`cw}apD!!)n z2(QS76aBrsG~#l}xxL$*?BPAMhVK>9c-O9ceEYlnWI=bP1Nxy~eBGl?E`#&Vj+WOg zRlWqLCkA7uak?j6da$cZ4knS_;Or}Gr!NomrZ8+z#Sjox977vPLk;T-Cknvw4|sNj zf4nZ%Q|ZZBM`I>HkSH z0d~_@{}(`XZ56A&jCCCxyfCt(SQOBY{jkrk%4SmWzE=gH=R+TxX_m33@{<7ubViCl zvQ}PkGTLB6obn1Q@#GYpjBac(N4 zupT)6YpPyg=D?RUb4|f%O_hUA@$m;h0!+)* zPGE?p0?Qo<)lPt+Yx26En9bUYd_%@WAvR4?Pi%^EeyK6w;3Wf~qq-*WfrB}mHhr`b zx6{WnI}VfOGjL#mvAi<@O7dK)BO)j+jAe7EQmGDJ6RfiLD|c;hoI(Cj!&UsHTL-vq zoa%f0ZX~e@#$|K>V-taumKr33BdIa>i=5}?fCgi^P2$Z{$w z9Nq|nMk^gw_7*#z4fE?b`2VBY{U2tfU#7-?sfzy{vM6hcK~+)MNh({UK}5d0flee% z>{``RYqf7H*7`j66oc9#G(TTR4A0ELn(z?ty_ckx2R z3acx)xCru9MKDNN$poAXbCTtGjtDovCX`$)dK2SIC%q1pp+q)<#X0njG4J#efnGq| zNsSp)xSQz@h4?m$!DA^)+k+rcH=EKYGd@RLlz)_*QWVKw7!ybZ)~Fe{<@GE3ZO?;c zpFncH7O#LbW#$W_^&1<*v%cxU1ziA5>?~jap7?=pg^rDGT+0pRW#IV=SLjB(wMzW`ecv2cBkhLM?$hEkWEI^%gi8 zA`@z^3(j7r`$p36?}vGW`%a!xqHLc6?-4+A=V1gw73bauhtQ{sYj23`gI-nf?2wzL zG%rEuvP~V)Y{%ckJU=Un*eJ6Nc(Yen)1BmHmiI=SJ^d0jgVl;BBk4*_vt#XnFIQ?} z-}##$2}PFj8d~=P6WM#5It)9yay_N^pm2AyFPZ{o$>y?G?k|pi_${J)RabscpJ6+? z1)r(5qj<8&k=uu}`Jf+uT|w7F3``j_UHFEW(Q+b+qGP1@(|A2lU^vy1Tn!%;PBNZV zCbJmX&~!I&H)-1|?*Pk>h<~cEvT*8jPx3HtxR-opiFk_+qf_@&Z1tHRV%FmGr*(c| zi(fkb6~LGQ#o^r{(7jwXNM~-})82 z^{Pf?(rs7A4xn#tUq8=+>_P)y2|Ns*>~-a~9DlJ9(O7(oQhuGS>I~3}wYM4qhPg9( zHygHKLqED%0lDWTO^*J^lN^{?a=0u;>!;B7Rbw3;#ab|US~k%Pkh{Rj7Lvi1Y@tH= z?D)#&5Lqq}ve%y?NPoREOT^K7&`#PSd&C_jo$sCAqZVG}QO{mtpE~Njzo$>~;XV7_ z-)i1UQ}`8CBu_{ZL4C*fg-bRja?uGT%9l$O$}D={H7aqFVx0;X9n9JJ5u;q>7{Mfz zq20bpuOJ~bTafh0pWc_j>B%2{-%%3t-xg=!#oNNR+NsOEk4L9;gLqk1?#cxnHr4Vr z)e51f=ntapbc{A0wtS?8tw5hw*7e=DOuJLv48g_i<;v_QSQHKS+g9`oS8!Yq9(6U~ z0@CZh_DS}<&J#szlCF}18>>o2% zh}&;7?KVEIQKK$>Q@h4n`lenDkF@fBdj^wsY)J=`c3epd)9cuhex}!PB@Ik|u_fJ1 zr;U63f&+|u?gnqMoUYmr%Of7W_>i4DauwByS0H8i$p}l zHq#ZTYZUMwghEaSl8#D6vPAl19todcRI~X&O-s~QO}tqcPE26K3PEQ`xPufXAf-SP zq}QX<-Xx%b%K<3^v=kOfXFknLcbcUAH^jVur4vEH>8FO7Nj0;P3=J~3AIY+NoHA1A znk2YrV~l9*>}vj0D zczt$ET@Ex?%&d{=_=-c0E=&+4l4BkRP5?L2{?&0{>6muDi_$mZ68xbrfMHWrR9U@Q zrEJw)hqLpasT)hj28xn7Sf2KLrF*sG1Lr-yeSdW#ZXq3+%22&L>7tt>QCco3cy6#YBxRiOOoTCqh92sX)RIU=?1A(5E_1L~~RcbxY>dN3v3; z=&03husibg=GXJXYwP?&vu%wVz@4%kxtgY%Yh6GKx=*Nsvt#>3Ylnnvbp@ zd5@y*!nB`dkll~WPh(|o4=$%vsh9035#Pw2SkWymHZ0yHS9I7l(7$2y2`)_^8KPCo zB}pv^e6hOky2l~V39=w5I$>IQiPXWIhW%=xF;i352I(=i~beKtlb%=7ML( zt$~eJFGzY9~MRAo+J$G=X}>?QQYGEPJxGB~_Gdb>%B-&zLNB17z< zEYHGBpkGkr_@Np&bUF1fMKaArz0*_sh>d-Due^gCu-= z9%+W4zukBLjh$B~eE6Jf^#TtG?NtWfeoE#mY>^AEZS3cG5hP{EQt)Nk|HA~R+;d+y z_-DSXX1R6TOE|3(;8j~eeth0U&$Q?JdV!Ot13#2T;ToU5Q=p6{zAtSZT&{k$XM?Y) zuJr5?Bj);iM15W)hkPdB%=Z0LIR3L|^Ix(WK(P4pr~g+So_|b&hG1mrNG#qqJNVG0 zx9*E<5!SN6pL&z!{IJ_^H_}-R`Y)#+3TzuEax0q3i}Fs_J3U6use~Ag3C)o}1aLU< zkdf}uLaszYKZkN;5B%%m_$yMI0)m}`5Aa<^lU{j!2U!XZI2w8%k-smWJ+$$}?ikNL zUH8p&Z3C`i-iCu|QJ>5uETj~po|;*%O!{i!F=UU2yKsShgXrXM1XRO8D%upg_#zsE zIis7;B$X`{Z+Sb_zD~fAWGc@op9Eo$z^AnHE0}zD{;=H>h*3$!MH1dibM$z=1|I(v zN%B+VTFK-L)(AkB*UCHoJjyi_Mh?h%vWNz($hy=b zGgELX(Nw6(@MZW|xz57*NE(VtUa#wTWnQT?-l1xTw9stAC!*m|2zS&uap#wQm-?o_ znq55+B73&W)E+li{kj(&^-kIJo=rHbUFf@NgdDfwHGOYOoaH4;UF+1MdsXVdrGZMW z`T3+2SRD$^A)7Xma^dl-XPz~xZXG!5z>o=gtjkc7b@%UL&q;8*VSO-}q~wtLr7>$+ zWZwTn$5i#IcH#`<$15A&&t2apRKFI_@I7f53+}Ew_%#hywJLMzy7JO-f?U?D{zM{I zp5dV+d9ucnr$fB*w&2>1|6SO=1$K?+$c?aG*55_! z=b644_qYTAxIm_f@#g`gPieUW>J%hy>nk*{ESLx{W$MjEjod9NoOfMrz^|s zh=CNqfyJW)cWQ9o@HkdGSB0DQecH=aiXpI5=bNGs!`Yh&iu3i0*CCYtN>0bul5xd6L=M|uV&4XjG3 z!Kz$>YyOECjA8l9tQiHL;MwziRfVyH0#UIpZs6R=%%|z|LnB3`om*x?W~TdjuCOpH zg+_Fr+#Q`7?zrS-rbOXe88-qL0;4sd;4L)QiGH4qH&DF|{6z?oAXLigoCfYXOW3US zPHuDuJX(9_Wv8}QS4Ypda4v#odH<4SL?9Jkis(xP79`X+C8IUZYp=-;mgdU3Y7=Nf z*k`ZwrN(5Ev0{9U=I!*k>1RlEY9tsda8aN~|F*OEn1G&@1^ENyU}^GiV5tz`Xp=)3 zBxQ=J@R9Fk2)73-7mn=xq(pAd`po{a^ob{Xlf4+LKZJHLbkg^B7|pq4^YoO%xD!H? z?79bqARgsAmXyC%%>_4K*EQEam|?my6pG3L20nAG5UzUoE(``eowL-Ww0rS<1va=X zXM`YG({`I7(lBLP1wTG;YdAct+k5Zq%*&!Z8=NitMmoLhw!_F}zhZvvEExJJNdJ?m z^S4kfpPx6=1tESV5*@Q&or^-cx_{a}M-E7Y2ufeltJy0(piyHXJ%Fq^Bt4*2<0@Sw zI`SQMcCUK_=iONMZl=3&?rltuP0k+!6Kj#!NEK{eVk876E;{lECN4gb023D*ea0*< zF-l-2?=g=;y!(^d@^|v#pKQh7fr&vA+cP##n_dUviyY6|SN}#u1dt^M-aA${l`0b| z9BH6ntev!kqKzkEzk!6#)QUlRxg0>pzP3F=YYr@c*9Ay9eP9r8VcgD4|qXG*qvbjnGBeKBO6`g>A;!mHymHnu1>q6WT7_A!gkzTa^fLZAc0q9xF zCv!@>v*$uH^jQ1n^98r$T`E5Y{L&nm-A)-6WC0i5`9q)}2`W>`ZgrLopaA2tRTCo4{-DG@IWSa8q6^J>Y_KAFco3OO3ok zn+tw)wFlr}`9`(li64sO^>BEBAx6kJE790m^vvu~MY7V_c>=9QD~cw*R))qvX0llk z1o?PF5+a)$CaW*i)la-a=f2dQn~aWZrm=`z=6UCoe?j;5ksGZ2B}E*s>JCVKzwjgtY}3R3AuP%xv;%pAyHrc9*#6p6gS0sJ80vxazl& zl3%@=^&LvOsj_=QTx@rITb{Y!(Z=|`U()q71P4BfMlb<}deQm^6mgmK;=OB8F z7~q#ALi^VQlJ~FWs797PNPIwTBtj(JG`l9&+NonwA)JO7F#kon)MG_f#-nJ$D`A1= zQd!6~khQ{;ofW~2sBJ`;zr8w-i1JYfs>4$Jmw@U;gmz6Cx}?^Xet2eu7$YDoTWGnl{`+C*a8H&N zvpgws#KWJ2PAM}C11Fi-lnrSmC{u#>2-{4P7I*RnOc7)^6NitF?_H&HMViZ=z^NQ8 zB*cv$Zq6Kwn2>#?(v&2VA(w#8^fnM#oesRAT~64#bp2(;>w_nMx>_eG$z^h`A7img zfADr_{nl}oT;f*i(|KcUplTS%+qcUTaxNuToOGk{RwTqeVbnn}&EiR#H5;})tFl?c z9O4V*#hz^YI9(U<#fRs8wGQ9jNd35=v-Zxh6?$L3t|z|k{Vk~W7RxSpfe{WtRUjbZ zfg|NK2^WT)m9m*GI~obL4?Tk7DZUr)T)Q%@(%QUW20;cGpx|B7%A%LkVHIMRU&AUSEe<%$2Hytpw++H2WjKn;3*mAd`ufk+*adVIyUVt7A^+egzMw zYoaU-S=_tP$@x87Jo~XbvK~&kS$WRv$Pf(jiL?=b;w=QA43|}MW<{B^cP^fPO(p@_ z_=mbM8TYBZV5BjvHs(-x>`qfYw{@Hrr|BYmmOS09+i~?MWa* zqZX$<@a7>zj2e*}sspnoy$J#7ceQhw^RJL9+om6)jL&yp9b8AL15bo=SVsz;g^c&e z#j=DtM|dSbPd%lQZWf9pLg9F+hsJq|nQz`XA?O7c?k1c(46+hg10kF+>I+}9oa}B| zS?Bt30fgK+!#c|W`EZBZU-}=m!TQFv)*gOzvj`X}xPoQvxKZNOd#-c$#tD+A$Ir9U z%f{L^vbFjAC%NlBW#PD;F6Ll)UC+3}q3upjhdBQaD}D(H3sHgl+~0IpS!HnKsGomY zGWSZEa-g3p+2_k$o0?nE&AA69lfa=EwIzb1)={t3h62Y&C;etDyh57f7|PR$Dg z5t3It#1n)RXOiP`&AaT@GBb}=-mlPcJ77P-R2f&|60B|f;!fCW_7{F(e(dLUYSWnK z#q8&pR%6_MGVw+)jxh1YEG{y|MK6BgjN7~TgA>}b=y3T0lIu_O#DC*JHl=tjv9;e1 zUi$YL2fg1qH3oUEaAN6_l;(UIFw{zu+XFkp%?%vjeHg~Fiv2rnTOw`Ph(XHhbzPaf z7Pp2$GMYfXvMrgm1&{WW%5ZrQK|AFgzGE=|oAsbS!3teZYug(Ix~n4De5TC9q(C|v z_ucRr+>z(Ap2Upm42W5tAR6nG2k^tZ7o}!d$N4`v1N%6wr>zwFEV2A<{ZVLvfQ9<5 z!!;hA@3D*WWV(PhvRB27hU`*d0t9XMN#Le1aHBz0$8^e{YVX`dP|Av5Rj?!=I18ex z-7W8+MqVStTr9Otn%emF!8BjK*g2L)&^NH|?05-0n=)XVFgr88k_)i4HQ;f`N6w*v zAu03g{jK@p<3DdNh=k*>kU&g1(7=zNKok|3a~Jktntr0maYZ6d%HFS#&gC#&_eIXK zNzPG5_RFyG@Ifl+%dI5o@D|}mpT01#7C00SiCoTyX4+$ zFUc+C%8yvD(h1z@uadGlkM;_D7nGT<3n=P;z)hke^-*JU6mF!+UPB`H;Vcg)8w{hf z*TlW*;{)B7Y6N$d`C%8ft&0cy6n2AGzK?2zla86pp#xVyIHV(QIMnxa8V+ru9e&sp zR3DyxQT4qke&mYJ(BTb_jS#9{Y4w-%W!~Xiknva=>}gEA*^f*R#&WWUHw0Mvf3zx6 z$+fRQGBPdb)!5@!y(f{ST(jq&S~L1$u*mQYmVw>+>KF~9=}vB%e3n$Sr`0HkiYgmI z{Bz&b`Z!4K`kPqx2cPgOY5Nx>*dOU!|1T^*)KceDMjA1XV3uT0mVf>_% za6u&<5r`AjL{8b8H$?1HxfRgwPL(pEAdUQ&n{}s3@dg3{c|(KCE31M_gwq2KbmQAy z*133={VQxBcM)twE#I3+P$tW?5f6#1;0Orw>qmA%nv#dqv;)#?Opx{xx$tJmbop!$ z|5Zx>UI%OO5SjQ(32cgloC&g1yQ&~Mv%o8hAKm=QQ0FBuMCW1FJRh~ailFV)n&1h0 zHx}=&TF6Y}F^?)$v#i%op1qLA>Uco-+?Om7)|=2-VW~U%Lc-2^j_j2ib)3zvX<{!w z6gLF;qHDDV?l*qg$`Lv~LOEqaI;nPBulF(teOm~=lO4o0H!SmIL+#9u6VHJxb5F~o zG2tZJ#+$2hxqOg*pLZ^_eyLEDuC7p zWo-;ao4B4g?EKWPJKWPE#1pKYLAv!@t3~)H@22m_ftQpd*&sC%u^9Kb>I$8(j6#h3 z;)JiUm{L}E)4gu8W`f%ofe8Yw6Qen=h?_CsjG#tfFSrvlbVm^~u4-fgmbz1cCjtZbNh+b!o zKcz@H)&FEX!7LX94tiCQP#Z6Pep$x7&c6FRhiy7M-<9ce>C zW00vha6jizRN2b;2cOW2WR=a$5TP~C+VH~)bsaHw+OOiF6M0?(?)2Z<-Gqql&De#i zOe(n@J1?IF)=YPZGZQ7@6&(8I2g&NIL7uUXfjAb_3u#itIzw4^6Efca!|F8Z7xc_G|6%Yv~7u>|Odo zJ`Lu(lF-?7!pOIRS;D3!nzBIGJ~%A4v5ni9OK~r{Yum0V5qG+CBl0^Y`J)Fl;9Gt% z?*LD?fZ?%JyjdB)VyLU(;jJ}SjuXSxbMc}K9Jt6xQ_euQ=_3=ml-6_M{|r$iqE8rT zg%1Y~urAsL(-ll~!*h)_3;aXRgVrBR$n!=q*xY`8_>j8eSpN4l{)-L=ShmL}{@-j@ zhatkrT*@;F8P(S+nY|_KUsPM@ zy?r{>ZOTNaYl)Ecfn)XJ<&HUOCkkfdy#K&wi}g2%7tH&+$J2(SpQJKAr zkqmwjJ2p7&9gXJ>(3j9mLic}|L!sqNv*n3YB#UoVEM7}1A(jDPvk_w)D&Lr7_?;Nu zT-0r?Oc?_nQ84XECKoBA6wHgUCmrbpk=~K?>6%F?_u7!wXQR*WE8I2Lilq(M1g&Gd zpL2m^UC%pAKS#?Bpx%ZQ?U9srOUx&6#_oPzTdp3Yn)Mh4g$Dp7Dp?E$OX7NC4dwzd>byW&-?ZjLR#6i+k$#xW5%XyRnU z&CZ_dCjy>EwFPZu7OZl(N0(zWpKF{LdD(u{S9hK@^ZRXc>JUd+khu4tX*ZKC!ayW3 z602q3%ORcOsRi!s20MFtg>~o+Z3~VeLS}0h7MGa+9-o-){=Rab$oDqda(`P85@xJd zA3bokW&61&zI3i}I9?{BY>@zgZi?gk-=OmG?LZ_T=yx@Fs` zJoK}^wYIWa&REAafePM1fPzw>nD1{=|9)(S3xj=%@B4a2eUN8L|7{OCn%vjAgmk@z z0Sa&uy(uQJu#O0F9nd~xnWh)ubV)E+zRJgk!=*u~nVi4K(jkJoQMZDb?oN4PA;@~@dD^cz9q_uo zz`GonlGDWUdaMHxx}VVX*rZ|LwR!r$!&Htl@7sG1Q{>UU>Gs3ootM7no=UqFbf;gK zL85rvHM}zjQWV{O^nJQdps~5B!!E?7pB^%$-^Tz|og&N-xC10=0pKyA1eQ_lkoIX} z)C`xk<&N^<$j(r%94AEo!_WOr2o)oB46?Vv6fB0zj*cJQS@6g(rGS-I!{iD8s856a zxV>q!TsUgMHF`e69TTMlK9T0KP9<|s=QIZMdxjCM_L?bBZob|B(O2N!H4#3znEurg zSAH4P?nsGd;X@6jd&IW}$&W?e-#`*-#=+b@|>I@#1dH&QOYZSHsQGbW# zq6A=)Z@(stPle{*9_gd-#Nd#xU5Mi~i+=48EEj4C4iq!TgUjOI;6nfXS^U@W`Y)gU z*X9k^2W?oVW@wem55oU_FRWDvnI2kFSip9_lO{C&fTrcM+Yb+sz}KA%<)ak*$oSRU z`b_&%oh$MyeUwuFxF7>+cky^p2^3;-67aEr<{&)+2wUu&se{(mB7m=FR^#tinj?Xn7DAEUKxxA5UOhEZe5cx44m&Z zm;;jKdh@19b{GdnT(7k zNlPA&#oW!{M0%-72#$oHPA-`XZ+j09ef0`816fCP<7==;@f>g>r`G~!bxAbHpSIF$ zwhD*xLK=jr<{UuWj)CKS7kE)OIP2ixj@ibldDiP|tdg<>L|^MuVdRC6T8f35BInB8 z93MapBUssI0}bl&cjGtAu1&$CSj6K5YNw8Dw+1-}AAMw$2F5g*$G$^09!a}olg}5c zeAz66y(i(%_VdC*8ILxF3%B&&LjUBJ$>LewOw46-?bLi-8p?}|4?Bz4Rr%as7j~|# zSx7xFq@KXzMuNpJADP~sshPLmE-}%O91~w4WQ(9m4 zJp#hj5t2rPZ`8F@pLD;1RfbKfF%L2gDR2*?UFehO&8Ir_b2d^;oUOzRMpo^>$w6eY z>Ih?9+tKaczy~|W8{9L*p?Ie)O z*4>+84Z94}qd1_K%etU3Tqc~RV959Y{5@bqPhBkKMJ*|IfD*HmYBl>Ra$cGV3@e%I zuMb!)Qm(fe1R(Lp(TmYiaom1_amCdNoS} zdA)k5$xvf_hw_QwvA325$2@EPT!f4A_2MMDYxB zRZwqi_><@fP`NUhN8_QKwFz-h69jO=>na0?XwDEoHjF zQigT8MMH;qP(f!sG`hEIY!{~Zx2#yid5XAb-+B88`(!B2sVv{g%wa#RAeYYWZBXje zH!iTyjM|EZlqL-jUf>-?r3C$1dfp(yMoh4^QhxO`SB_Ujn+@eypi34@xFixg(LvY66=h2gJ(u1g1;fyZgeSN?Oyj z&<|$XQI%=m_@3fWa7NFv#`Nk7Mt~LPU90hiF_*iF3}X_9F!YR>@RZwSy(;I7qCYMF%*?5Y$~f~ zmd#oH;USBp2TD12?Bgex;{}XgM;=weUKj-rFDKHzZ;(T2GmM!8b`69*CTrj~lqdV{ zVkPmeWj1t5OCdp=MG&e>_0UfPsa$I60CMwCYBV_01BHsvQB`EE1JDA%c10Q}OFyAH zI~x)(Cm*2@3ZF0}XA?~u&cL$RW77Ehv*;-WH4=Di4rfA+l$`fmf}k91=FsXN-=X{O zVzpS)>TAdEE1$rjG{>I3Vm<+pmvI{mlJl25Q~}kOkw^`Zi8dpEWAB4j{7BIvIxj5g z$mK#Do3I6p{t2`d621c~pJejv%j+SvbHSVoR)uI{lP7E=m_UOYS$_I{ zGIICV#}%pCiIuIQzN|6Di!-|9=y2caDrrP9+pHUSwF)Dkzcydxe%^W8b52R4UNDWD z&HDKA3M`$Y^6!Cd2uKTPWW@=s1Awvalbp)N^;F}r66lp8I+tK+-CUW ziH{5e?z$fdeR}PG)K5AF(AiM!H^Z@i8+H_>YkWufi@!XiWalS=MLTVfb!XF#R`ISa zpi%OG$8u2=4@5ku`${Nv)kmF_K(x4Y-DB^yKeD=I_x(tWzpaNU>NTk8I)H+DEljla zO|VGCpeg4k*axvGNPW4-cTNdn2rvHNQfKh@`qXc0u{- zsQrXCh~pVBumN-26j;K0HGr5QI6oxt=5Ub(FiYw_$v*pgC$hHs3bAr;0>U9zJY4D! z1-=gEQg4qDCygfkFTbCo!+f*+?gth>@x<73TXo&gF3E^EsL{)p#L+otf9UmUi2H^# zo}bJ_UxZ$&doNBIeteraOhWXUtEyXeO9Gt{JBOCYzI%9XXfPE{n?*oL2&hRMwDMU8 zFDft9xW{A|2v^eud={`nu$jVV9>YWTIZ=7(C{@i7t=DE8wIVXY1eV$R2KVW=_jBpfQaC+is3;_9hDrPTwnzcfY61W*9GyLzH9U$4@UX#!C$Y zn`!f3#*+Wt%m0r_I`&r>Ux7 z^O$U`Qd%d@*Vz}AhC-+!!iYxP$o-TJ&|Yxhm3{_8Nb;JvG5aze{k~Y z#&Ag-ZHF-F%cZgOZg=_Nq)KCYlFca#+&HyyWYry(#`H#ft-5eB8$}`Cx9vqxvj~Xf zH~Gt3LYq3D46?@2nXwjrfvaEk9Lr&<&HkVz9BZUXPct%u`N4;%^~@#LdnJoJRBeQE zSB)b!I>ka__euF2{7W?=AuR~0ZA#f&>dKKYA5O<3WTt^=vKMONH@-bmGPzZ~*X}qZ z7CN)mACTjoN?sApWdnBFJ~^VoruC+k#b2}-7;xj}Di^`IJJ8a3iSF(|;l*Ow)ah4_ z)tS@UgPCwB^~~rfr?Pf*?~6dT$!ZMM@xN^n`b&%pq+xsh{WL7(9Ok;kPuB;H-+uc~ z6i>u7pZPDNDyPEMY5O&_PvUs0?`s(nAa8h=%;)Ck_JyxV^wHlal~p0r4u1~#viT}2 zAV#7K4C@uO#Ic#2G;2;&ruXqx^(KjKpm9m%^Y6Bk10F;a_%bjrD~O>=)$UdV_H7$0 zbFqLC1Qw~ z7lZGSy78ovG*h9_&03%_R^yPY@3H+jfINyW4N|sNBYGYs zE`C~SzqMEbZVSMILL9qMCg=_Oid&NH9}4UHiVpz`!uX&;7)o{NEO?6Mz@$gR#`>qm z=^uzu?KsLOSM34;NSu`iwHQ^P zR|R?nh+IHH>Vn1>Tfs~f$nf|Q5pvobK%v0H~<1y|nE4o;Jn zG&j2@Wc5mi8zzZMRW_qtWR=N@m=9*SMe0^tQ8gr{Y_?5r^S1`aw>*O8Zq1_PBJRe2 zQ)F_wnE#!O({ZmxuLm-Ns~oTl%II1+y|!c**`>4wsMuX>^UIS=Lo1(fNgg9F_AShL zIPLv-7oa98O*Q|*JW!Zo93HUfe3g)QIvr!SSTloPZs7X+e3H+61!~p{y{tNS3I%R( zj~7`zndadU6|6?_utpnGS`|w1Uj(Lq@2 zL(N6Jd&U9X+LzP73GsO9RFlKg`MLmikjrNfjiqHj z5cd~;$a#%N!aSs4ypuzgICh~2YroJ z_f|0l1uiIy9A76N5O%2nv;$x{{c7w~N1J^J-R~`>vMR-1gB8U=0scuBt{zAu%H=B; zd-~qGb`d0Ds|^W(aouU@p=T4?lG@q!B=*R58P`urMvMuU2DBIDpWG7jeF66 zfFbQQJVzAaHdPZgbza5ngcWawftCUBur2ZAo7+u_noWeU^$S*Ke*^{%hM= z`GK(Oup3882ij>&&2D!>)UWAeNK%4Jj5YXLJM=xzo|{U~v^WneEs*6mdmHKK?3SkW z;j5BbvZdB+i?teZi1OpV7qd~$%UhE!N-~t{o%c(k8>r%|;M%$8A0)V{HiNAVDSHmK z%D(ZN%(INNFp(oA)#ly9DQ3y0*8o~OMm3|cKnoA8Y9^6C`|v5f`jqqfOCcov%$vXj z8!{6RApbR9^na-T|L~vAUig=SG4aGciPRr=V&t?5N|z~x@`&y09wR@z?BB)_?c5cg zAN1+4i4U~Tu{*Q+tIuSp4m!VX3V-=Hqj*>gCh{2U`+$onf81L=X7!r3H#R7KXxVHQ zGKaP-$U(LAa+$Es`UZJ$qx6?A^^4+q4(2uCCjgH*XKcV73-Frc=#pX`VSm1Chqf@u zHAODo1s;&$g$qvhK;xtyA+L!St=`1ScNJftL^lxFLLY=;2h4a-&(F*FC;%T^bm+6B zThhJNa&F921X$`oxD$M`Y{IH+dR74f6*hOan|QM)w+o7Vp>vZG)G#4o2ju;qhRoTR z1Cwfe3DoH6%URL`-?nfVI!@g~`DF;{nB)O8=QLpUW3=JK6}!!tdFI|R;9=ASkR8B5 zklO>pT=+yKMVL9uv__`9A_ha#Ddk0wa2lO3v}3L>EDGTZ6!u1tkGv zOA4q%1V$BIUFA<}tR>oi+Eyq`ZJIAonh(2)pyPm^J*$b{TLjOr-a3{L6g3<1AW}T? zN8b5vl2}9#fIrsg(qC)07wA20S;6SY(Sed7vY27p~>S0YI_P%!o5rdsLjZn)8R*=RFT39y?KTKZ)sq8NgX=ZIcjtBSC(apS{W&Ka; zrk<81M!`vH4;CYAQJ&9J7Uz?$3f^r2;NOmMWSsxjTY<@monr^%+BF$$#GrRlOEZ}# zTbrF+{UVOI*j!_?M}&l}9-*~M`;&!$udM74C|{_9+E?Rlf~!8_O_~HxYlAzpxhB|3 zRUwLaKxbkOi^P!Jl(wNSWTzxaXdBKFcK8-e>#Qw3n3S@Q1ts()^6LQW!!bEz%F1F z7C3<9)U*6N$jXCWP&|N_4u!S2b$3YPg^Lsh*#e(PfmG}Tvho)>IXMOcpmvP1qAG5+ z4{-&5cz9q;+SZjKm>_{FoTCu>aOh{89wdPz7;I8yX^L=SqptxDaF$2iS~ zZd*7z(GbACh~j0VVTZMMr5Z2O`0HE`kQ&P z+6mkg)pm7)LC{cwW^P>X1M0SdRP#7d4?s_|ny#wNR>!^U-e%u83BFeciQbM9B4!o4 zA0$88{d$1OAI;~^O|wIEN!k!GL8L0w804ocAo@E8o&nG$7V51MPoP_w!%j%z&B}?< z8gpl{#X)1Dgb&^Yx!l0~gU-pUJBsOKLU+B}g48^gfP z*jyX0s{UY!882Sef!_W4Zj;_`%`yo={0iP@0fnj=;NeR7ks_8OAOHjCgy&biFY-dy*i9np>AcYq*`k7)HF-IOQSG_1#y~DLCm| zHF`l|!Fg}Y_SRVacp(qIWCRHyj);T0qUV#YbGB5k16$(bM}(Wq6yM*ceXJ;H!0QkB zY>K3r8w&P5PKySEkn3);RQ6qAyg~yjx73QyEF>M4#0H@Ko1x#7vc65$e=OdA>grB9+*>XnSZi3N!hhg1%^+DT>jR|?T`lSf!tJ5>70lTktim{G7r zQJ6d1OVmt5(IPNBM*FhITPZCu zG>tU!ZBC^JJg5Ldu=Q%EMR@Z;L4XOca}ab@MM$hk&(8uXO?ZBAJI*aTgd|Vufu_a` zF_Fk`3=}_Ms8|elSuzrsxc=n-iysBNDbS?Z)ouzpjuN1`N4bno3%HKjNMykz(@{6h zs{)<&@QZa}42yv9y}QXq<}iA}=)vj!*|F_z z5CiVg;p6m&_?OaFVXRUdZg@zT#;q1@!s1BA)De(q8QI(`+`WY6Mhdf@=G8lE!7|R? zD~k;p?cF|87hZyV*e!ZRnC41aEh8-bvZ-6F?R%ZteG8Bk{F<{!uOIdN-mP`~-F(}u z-T-PHu%>#dye|#OgNpOlmiJ^4e~1B(Z|Z_&xwhvw#Kvp?@0Thrl^-LRdQY(QGF$%1 zRu?`$`1K*ipk*Hv_O8%ZwRejW^`o9jz$h&{cBQSlm7? zwr*@nN!!k}f80&6$O29-{ z0yS1htUca$_YhCI+J~@P)5mH*`~cuuQ&>kKDGil|6dL!?^7*-Ef5Yczn7tMsNK2m7*GoDjvM!#7ypMy+mj_NRPM%?qn z@r$bRpi(jGY1j@3f?Hn?m)bFCUZ;3g8h7{2tkw(&dvJm~b+l@JpT_pvr1sk9;rUY? zF3%>9Oe3B&B$|FY@g&)Jy2otKx2{0wiokW0pNp1*n_*}`IESrG)UNWYu(OnFbKh0; zxORV0zO~)CG>q;xAIeZO7;*XeI_1M9>EC-nQ+`p43>D|gVgVf#RnOltSrKm7$=)tIvXY83kGk8u@U$Ndbu`UEdb_y?k)21DIqz<2*3 zUI6XC&e;;@s&|Z329)Q}`l>bd8tq&cxE|>OM~egifJhcSlZ`)v$C+MDMkU;7dQ-VB zj_+yzMkx(oUV*(#MkO1>d2daJt)h8MS@Cz7Cj-U>+_Hy8Gp$b<7Lc%m-Q0;ngFO;v z%P2o;bH_E|8tzhK*~Hy+Czzh5sj?#o*IXdT7VpBcY;)E8=8MGyTF@<@R2|mF$AE9@oVpD)+=f;A~u3i7h@#yq} z9-?vBeF0qvDh{Liy>33zQK%*k{O&>9Sgykg-P7n6WanS4W2mf$|F$Y{CPVk_FkLLY{ZENOlTlIDviqlBPNS1I`h5}q# z*>~^H4sE)$<@s^b$IvgU_Ck{n|GK2w+Sw|==nXkxp>Hjc8evK4!LmY=nT$jnqP0~& znfze6Ci$F^=Za)Os)^Y^+6W}w!MfH|Uknf{dMt%>S`tPwCpn7JFBgg>G1#gXl@Mn8 zge|HuZN>LHOHY-JRr-~7`f=0_F)u_bu2|Ox?pRY_#`k;wK5JQxLlpTg!|zhe4U5^m z@$j`^B-c`C|HTqWxj-6Hv!Z1tYbShJO>BR1dXpKMY+l0W&6d%2zsi#Bx%H{m=xVKW&H4rd~dD+%uy<5aPXjePy@PBiqe zddkZW9!=_1!I;p~!AC2ePL~y7ZLJN0vwfkb@3^e6MPWFfvq=rO2XoC-X^k2g#ao_D! z@o=4k;F9{o4PW-xdbqGpI^Oo_Du0>vB>jB?EeDkArXYm?!8}%WOPZR$`_`Wi1#)qm zS~(0O2KiEf!fDF9N$6kj?BY+RMqXK`TUC?ZDvn8fKHD)6d`qCU(Bccn08nhVl5ajA z7G0v`xLfo>qegyWrF6tUC1a=upfTpY0u^`vgyph!LAJ~H89XX!TfYP6_uxbU`5iL&i0xE zpc1SK@cO{p-Mh{If&VBS6=);*{NitXd!~^#07;OcfMRMS?r2G}ydeNpf1=z|Wb!DW#nI`1gmd9aIZy$B* z9OE#DADd~qpJlSbj5;+k?l(3@y~Dd0Fwqd`<6I}yBj3HqY)WQQEkGcq7+1D+e(f4E zIIqijxK*5Kyz1M$IJ2F!7-Q?gztryHWof2Lzq4#DXe(4F`Rlje_8pL$H4x|dYq7>!;^VbPSJz3KpBTfi2v@q_his`I$(^uIe?n+bH74a^Zo9V#TH6(UgXdi10CQb=Z)*O&Ody8ad4yW3H-h(t>AZ9?fP;aiwS<^+ zC1i@G*jLU6hMG9fC`=ph3F(OnenCbua%xKEFz^^$lZ}z@5q*j)gv9(|DkNXp7Ht}D zF7KSy&ZWzjctglYHO7st!VD%?wdE)9JYuw7MFb1Yd6{m?CSfjucW9W9UO^3#GsSbw zs&SWLpHe`A4^-Ssl~ly~xxNB~%u9C=R4-li8x25MD|>?X?Gc=AkVEtE6cD`m!z@X+ z)07J8Qr;S0PxMU{kRKP8?*zUxQGzU}GgZHEunPkELa{~!=o0t6TZiAYxppE#B zbrl0#Yu0z*4%Yl|W0xhgzv4nuSW!9(U;?dXjdXu!mnUIP>Wl^SpTks?N`BgXb8F_L zJC!UCpys>=YSJDCSD=UuYNkWhS&0;U?)Ckn!1nv&x*WbW+>k`Jcp681 z%!8tb<+4XfA;W`h?lj~gi0=hbBZ6`fPmEGcI1R2?C+?W4E$GcQR{c&uDJq$PW;5bOpyk#wo7hUr>xFDn7jhswN(gUp)amXlEK z9;t96HZ52T)taNT$PZ^+s=geHktsCgzHGVw{)RMF`V%mb)E_f@^~j#b+*ky>_@fRg zadG@)@d2b_-&sAiP#R+}AGH(|&CNn8sYvl*c&;-hE<$zx;!4lZk}yGbfqVo3li*)x zdiKl!&Q6QYLHXZ{XDXB=kd8^aPp%c4dhn&NC?pW+L!3WoYx>k8PNE zuKBnT_KYY#C$Pb58&YDI&AfQuUy8s+aUcwNvZG+2y(8q^;!<>&9Z$&jUlWESY>$ww zwL_N{^<9$ghWW0TQi6&`-jTA#yjPBSAV@%rYMI!rk3SK77ryo(gB#z&( z*$j47xnW1_Nzkzae2>iUSSp}S8fRbg2#e7Ib9J|9vH_QQFLeH9REW0Cp-vsC3k-KV z1Dd;vryqloYQP8-CdwT2h0MUZHhFLlTP{F_W204nRol5t#_k|R2?d^`#VX4YzpIsd zGoqzkg`c5yBUMuZ4yeVMccqHrESN3T5Vv2*9(kf_CH-7SCf`;L&r*b|9nyCveCMP& zm@||aot@-G`6WWd5}K>?NN7cKp=Ar7 zNvyN*n7!{K7EQ;SKws(&^LC^6ymB>}fyJKNyd`$mAAZ(Tn^`RxBr_+4o)5b!jaMz~ zKTi=yAA|3&2XsV3u1u-fLOlg%*58%u&onrU$krFnWOXh+4eoom^BezmN$50SF^flLi zw7jagy=mS*i?*D)6`{^p<3x=J5e<&H)u_t05IDEk`)qA<^xT>j&7*(&oL9p{MVcw< zdb1Zg+x<>lL>1YCJ0?vmSt^PNVhVt-9XTEDGuAN;nHdR1G*~FMR2b~$5D38 zYP0mqHT-Ou=h?Qw#*>z_K>TVPby?>jLJERXoj9wf4s?}f%t^dAb3sH~kgSWNIdmU@ z0A9kI3C8u;gZK2awp*)`PS%7lTsRpoPD%5Ii;RGSybVJZ%Kz&s7 zka;`q3iOW~baeY`2wg4ni@#4i2+A@jClYPoUU?Z((U3QJ=YI{;q2oiiVH5}D0>opp zVF=5;aZ`E;#@W*I{Of6lfABxM)mowL08-k+>%7lL^noqMG124*0n2Hcb_kt>5zTSe zr!U%m*AD5bFrH+-j3WozBtUsDJc(`@3$OJQb>C;$8oj&F-~XMEf=^!qXP)d=Gc|ci)_TFsD~V! z(qSV*9>H>iU)PgL{eiR?QC2`m)BZUu3hgegG{1T6T6r7PP>_Ylv~q@S-FKzX07|CQfPQ^%e&dMU4X5zxb2@oKmgTA*UOpDe7DE3+WT65lvl)dyguz>c zsg9!x+s5kXCm?Vp8MTtBnWm-qVloqxrK@`2UhQSwsu9twhJb|p)+0M4iIoeLy6F5) zK(U4lAOf{Ur0&#*I!r3uaRbOSt>~Na=rxwaSd*Jfpo8XNP?ib&YoH$7YfEr;=!PB5 zFStrD9bh#;fd|>fhQ!gef2MzMl|d$& zO*`;RlJMiW^jGUu4-5>;&q&?cUvK0zF$FYCw8~t0Tu{*dGH~$pqq)|r?<59Mb$K@F z=fkT?h~N0vs{?%cRXQ(i<^)@(qc+d(dj7{g9^z>{yXPo$Nvc2?e-=K|I{)Sf{4>mV zrt@L!IX3GZ?0gEHyGg~&t&F#Q74#xS4$`CB)5zyrA%&qbY$y_jPrfw$kM!i_W)8cUnhNHqwy0ACcTwG%#yluJX*RUNZzPA&SqlsM7m{z%YV5 zRsC(isS)O;`_m`yxtKH~yK9b)s99UA2VH-=_}nJA-#IK~bLMc-5SV{Pb~@Ifm))H} zw7!6D&pDNtxVkAD5oa4GX%xJ_0iATNKmLN9?5ic!^2_}E2$-w>+*2A5eA}u6uK-i- zoW>(7(Cf8;La7Lz0i~C$7%D;(FXb(Tx0*3$6D;ra)`v^v;}DzNmn1{mTm%<}Ks|4h zXae!kji%`wy}lkFF1<^l_%b)OaI2PYZ59px$anlZMz;U+P!x@pJ8>V=%PcktXOoom z6Wp$DgfHKT1f)LUZ2olxN&Lbs=$nMwK@FlgbOky5bSDL9D$uJ{EROA29}9r3g<$IJp!41`g zFd&qVbrS(>v5tg@M(e}qj|Ra8HM`zIP=zQ>zjjFSn`@vfr0q@4c?nu{Wd2cZ_0JLu zrD8cuaYe@f?CEgh6RPyFRP}m=cP6ut>DJTo!iHQa5(esiAD*J$-db1!j|M%jDtjoE zcvdM@Aqu8FDH&fV0y>KqjOxDy=VYd0qGl0QcXaMG5AW&{8XKZ_2jHVFGmB<*=RTde zvQ*D49SV>AaSHvWU$r@SC-L*tg^*WX#?yW}6&LIHzOGB#yrnDms=H0fvg(qoKfJhJ z+pv6dAs11ymVMbs@vD54{N8Pu-^Mz~w;tgPgVNr#S9aqeN_6CQ=tl;Y5+WLAv%Y?) z@6wdz7l7sqv1FNp?B};5arEp!tcsLW>ZZ2W|pi$W^$O!t=Husn<(6dY8|1H|#ou!{VFeY{s9d zzS3Cu?;$dO%TfJ>r|^Fk2Edv@!Kf`0)&@6v%9v~{^>(Yj%oFqrc%Zn8IeIPo`H8aIMo?dnI&b9YY7rYrP%nRP4}-aK3-o_k`!6EK-##BH4=DryHDK zZYpLU@o?Gry5ZJ$dR3|S=Lu!|*Z_qUtLhlaa>w;dPtn-$btNOX9-jl(9|_RQ%5%`c zL;U&CesS6Say-P>ky1WZQo-g-T#vLSx{4}ud)zb@xk?E|fX9}W_+qc9IqRsJrEP2+ zbnSQrz1z#@{mi3ef3?>`OF_i(6m5CEfp+;;7SVBgEkzNmQo+N$Up@U<4)O!Oemuqp z^6!i1RB3KdWh@+7z#`+wDFNAou+ewOrynOd>osyIz2IpzhPsbq#O_~_SzZK@C{UH)Jq5jK>u%$vCxkPl_ta35LLAU=Z_@*3aGhMVUhWPL!o(5kZvgZ zk7$7M6er+M=7Bo}_$xN#$GL#eDh zRBXvOtI39Mds3R;6%q>wvY3?JFgL%Gl{?}tOwd?=6=uA?II?-I!$`j?SsZhha`BHZ z`1BV-x$xpJGd}VK-6F{1OiiV+8oqG%8R`pCB&F?+Jg#T^S0Qfm1oO@wY1?gTsQTE? zEa8!3xY3!ds73Y)TQF-nC3@_i4kWe+#<$@X6RY zUA3W%@-K;}Ad`*0hf(RiHKOzm)bIm&Dor-GS+S+wpWN%(v-5{0i0RX+Njn+(A4V1D z{Q$e(^dOX0Rsy}uS3{Cc)6gtFBZh4p90(Bj*U|y2WXnVtdjn(MvMP^CvpAP?j&?9#HF@D+%fc=oY1dc zk;i;7KAF*Meqo=BAYbGfPfsr~uCP@2Y*yNRy%iy+9XegJ?%O8qbL;$LWek~5V`OLW z9DL;Wxt3o!?|s7dzV@x|FP^i)6O|gNuWoTucs?6XNR#%`b(8`KRl$3@iQ7-$ff3{nrk{n0a zluMS**bIU7Q5hKg6N5 z=XWSPGw^r;q|5fbGjNx&aB<)cEtbl1RqqCt-d*yha1J~}++6l)2gHQ7_PdDiGtI99 zt?Az5 z84pqkUZsPqz*eL@*xe3cVax?Ft%z>PvoWPTP{EQht?maN1!HG zps9z8cu-9YWvND|1z-!T=Gx%uu6axkexs6|p6){4puG`1aJ#rIIl^pf7A+FWEfWnh z61{OPL&C`D56>x8Jy_&|A9{i3=3#TQcUNv+j_EJ-9W866)!4;v3~ZfP*sL)uEnMeq zZr%bd53#zb@x@t)B1p5(@8!|W>&>gQEEAiH7`GWeM1{@FR_*-#SLq{`spXF}tbC%a z&oJtYj92#KP`{t|wq%nDQcU|_wA`Ua6^vlvZmkN{Q_-`cFqI$KwDQ`T$eAx_r<%;a z0HH2Mi!it5xx3ZtIF1A=Ic?K_7N-Y4owap+vu4@uQ>WTljN^cQ`gKD3S@&hO(9-(<2~L`Q z+EBw~wNIK-T5zr_k_?o!@C0859+U@11=cayxG)_VVj%bn;GeMjvhxGKUX*S;uA#%PYOIv4Ecj{>3r6iUZR1fBiAEa zp${?sAB&N%7w3brjNm6~LfAB6rf?B1<@7JWB=!bJZYA6on97z`R=Gm1;C`xh2dZ19P0BpRSBKecm@bY9llx|>MNr^Cc5Dd9}FpA!# z=qdm~y)?YRCI*UcbsC2JYDWWtdY%RR55|JhE+Uqy9$6%Z$7EdrH|mu72?%Ki-4r; z`!P{`M8LC+JKPkeyV4iM@ltn+wTZcGITgzX+px&-+9CLcOK40*1^loZK$SxIP-Nxj zi=pML%`a)exy_3-E8&qNt&42s>UF2dm(JKsh52p$RM+M?pLeCYyGnm6TqG(l5x7hHz^UY)BYuV+TTs5 z;M4yc5<9?BmHP&DO7>+Zk_}?kXXNsm1hvOzmENkbv_pO+ZeNQ&;5T6=reD2X{Hc=^ zYWig(FGQZ6ca$+`e5m8SG(hLSZY#CfpR?PFnWwev*kwKTXiICj3hxVEd|HL+VOVf$ z$ri&~(LfDWayBqe*bW1if9nUyJks7(%|lWI?clC&)gugCC~44W#oD`D8yx(nY^@XE z)-jY4+?S9ljg@Q#krqMFB#%^_K&C$IoU1(?%@b{$$S$un1ZoTvxMq{F`8tN=!oW1| zTyej3s>dor0H8@byB|oe;wRB0G#`C1Etl6h2KB|r4ltjbRb>Kil9rr_^ zCAnVfhEBHAfnZB9NRM?Dm(7%VW!}8Qun;drxJ&Ohq9Rlk0?_NGutRMRFKD(y3JQb? zYsK~F7Jy7v+K7TV`$D$j1ZtpXx2qqm@<%ukTaY9&!6FpI4Z0}i8WR9)98VM_At>!b zPQ$pj$-eTsiXhGo5GK))13}%y^T}nDcAU~jQB|i^jAZe6sjC^=43n?t$!Yr_=9ffFO9dF__kIEH;NfZ;xK11@FOwuPGt@Q;;E(g zht@FuySt}L!mK8)4=@E}w~c1n#CD~>IhoSyT$ zBF+s@DEBQ(q!dD$4I3V=oNVdcDPQ!{tl;h7dA(reD6eikbo$5$yxu=6y2|C2-x9jg zuA;(#8}<9x?~z|)(Nl5;&^%yz`rMh zB0DEhoT?3_y=anATJrH=>a)h_KLjbh!3AP@InA}Z4|jcuEXB>vb^}SXI^UiNk9MKd_Y8?nCqq1&tmU|?BB2)Vg7PE+U<;Rt}s{KIA^9Wo7=tP_x&T6 z?Ra`3(|4aSbXQ-;$mOBVK0k6zGseIBqDY?YsSkjtHLA3REnqbid%oZ16V^`$Z ziB?im0qM5uyb zLTMcIybPf&!hmwv8Zs9I76Qhi1l2)o7o8b7AqcF$rl+e50Ocsv@U&!(CjYNQif<1{ zvIPa3(Pmj$Z{8H0St7{rD9B{N0As==W%dTOOPaaHfm)J8**cE}(&EkAp&e-W=g6gR z*0uy5eb_GTR%fw~^7k1RDO;3r+4ap6nYwHQwMWQ<^nM=vu;cpo<5Q@RcQnD?skvW* z6&3VBxzm2_h3LBZA2kL=xPa%U8V?_?tbo4*qRGg&wd{zgcfSR!_TJuq*0@s>82@J- z35eaXl`OXHN=~meB%rcg2FYp!=SWaz{4&Ln9*3IAgqL$@!fvpZE0aw$7Nos&O3<)@ za&Au9X}|LaRH;zQw0EbXd%7akjI zhT|~uGik+rf!ia;VUO8MBC;sHy+l^qBeUi_sP~KFz;8NBT20)opAT$VJ9t0>Y=2MP znjOk62#KGjs{h_NADS4_wx((zIgN!H2q51)sg#~ImShunXw;_4 zgp~86>tJW%a^&*X*HZYZBJ(i}x`ky};GB($M=z56VM<%B6;HUGytZs!tysU?bMshw zVh3!AJSg`n%H7ckL>kJvS>vpTGrtPYq2W7iNneSwqu2ps9%HG5g3`XF=v^AZe@3!C z9X0;yHaRvsxMg+5+IH&7YRl_nlQhGSYTv_A(rGmVsG^XDm7OHZCh(F;TSpZ^euMJJ z3EmEXsg)ueK8Po?QOsEZBpwtqahk~F=&Bn30gD8sakJpoAplZqZ&2z|3=rdb!+T|u zS{X+tw@P9lfYn%-jMO}watUJm>Kk26fmm)tTrpfxk(QS6Nppgc%6f0xO19Kh{({KZ zVz0Oi3?C8*%0%i)tU8BwK5162Y1wgz#&(J%Gb-o1M54K$)m0=V-h? z-4NxHWJ|!vty{%Pt91rh7=yc>b2x-w6s&RnF+C8H?r# zA9(B0i|J83OKV_Iki>IyqBu>!+cMdBN^R3I26HkM#R(*E!8tUjpcNrlQ4~r;WQxEX zwo8>Z5KKypFqo_57#eR|q}zyY@HyVGRQYTU5*cC@7^Zx7I-#mu{GO|*%em1{nBN5` zg(T~vU(MOTeA@0e4!L$Bo!(W9fei!R=Knb*QIu{R|Gzc;{-aVIf^@Kg{qfH&k&ZHe z**$e*w=e25W1P3B&LHcyG`@2A6YbixTj>fa!?VnkR&4=HaAZD{)11iuz4|+s&P|98 z#uHP&!@hs*>wOjCpW~k4t?ovUMtgBhlbSe<2=9D_xj%VbwBR=y8k@S^YJLBIgVpK$NT+yJ)a;2ZiNgBxzzE5 z7{C_Dw|AinHb&fFu{sEgr|WA9X41LXhe4Y;$r2HQWO7t0!qQ_+<{wYek7AXv{XX3K zWP35sJ{J1tZG{Lzo7dAxT4utMHKppIUA0J<{k%l)`gVc$kncQ;zRpai>rdIKYWn!ipu))IKp)$08|?kZ?fg7! zZ^a3`^XaVCpD!z{J371Q@ygC6a>1RYfBHx2O4jhFq=`~Dy5VT)Fo#$D|G|L%XCQ3R{y!nP|1k{vf6i55Rc~$&C*i^5 zJ59l0?ALF8eKpo;&u(7`aA|?t%Dg+Q{J`Sl1*jAgp2+X?qH34dv~m4>OiEg zI^l&{2VXP>t!=K(05}T*ILsNQ$lhTKW8rstOn1(~=R4_Tja&Zu!${QvHxf(#E-RF>0P67$Ln#5 z$Hv-J`Sc|$RZZxD%AHxm!iDRJTgd!4*4vFaPhxasTvnLxW8F?L2;0a9uU_IU)?C>7 zls6v~viB|?za(5Yri%#cl(#Eslg2*m-w3#oscv)OyLD`VQpKT(6wB-N9<}!ipZ6&h zC1MTqa0d(8D-vifyISMB8{jnHekLfAZxxUd-nEvb>^EaAIor)xE3vyZokvp~EdUF5 z0?1MYgU;bzOv)MH)Ovevb_hZ+v{G~MO*5Va$iu)y2f!ULs^mNx4C&I@UgL>aWzX7k z{6>l8hlFy5kC@GUKN3dLLvX@!EWCT$uw01MY1URt_6d$b2otqlWCZ2Iz!pY&BCc9Y z^sX^rWDDD1x?j(v)A4_?W&Yz{0Y54F_+RS(3xO3EEUv=ln5C}U>7fywmHGOaz!<%o z^^X(^e}DWqtg99Bb~%}2&8cvuuFsWko9hnZVBjyZhuNBIjM>#cVROF;psx0+d9eaT zfyQYqCkDMqcEruu^?mYhKXVX;=otRqCru(SAtAwy-Wu_kS1K`k7rqe<pKb|~|8|d`C^_zAy?oB=ZtW_>!VgGdb%YCrT z_}1m8 zNX8~{`6}I>4^3po^ySTA$pnz%<=~Zh>FAS{^vGL5eUjlVfZ0^k0NN3iz0rsiSib_= z+^6_jJ*PH@DutDkw7o&DZPZ|DlDNBv8s{bBu&+p@^tQ+ zYRx@?Io|hcx@vZKf)bp`z)%oon_Gs^=uXl$ZmZw0ke;9}W6#To!%pZHks zAuYjCrO=!YpG-u?j|Jv&r@PT0#IhMQe0f$I-shYM>nk%B*>iEeGUsppEU2 z-3Dx?z5a_d)fcSFzmXk30#IUl)QHPH=sVSNAhPFU^Ut}8T2)%f3sf+SQ`pM~He9xoQgZio;QeR*k7#xG4e~A@5KEC>6P?qA%bIAY%P5JbdJWqBrcKUNs zlXx$(3HdSh1TkPT;EF|#dK^YY?@80Y3VGddzw*&G=(jdnSv(;>2L#lkvq8`Lv$X*; z^j#!-D5>BuFU&FcgH8fB_a*f&-67X>03b~HYOg>ZS8Cf|an&Hk$WTN#2@FQZVA`tM zpzf!SgLP$eA*S{|pZ`R}bGm$tw}mB}IY((%Z}0A;qRm4uP+&?Xr+eBg_MXe@}i-OY0#g0}EE(7z;2l7S*HC3}{)b4UBu zz)2|%lLc(+-;ZJAusA8R4)%CFn+Xc|Q=w@sDf@ku8QxoZ^}`7KyXInV=MO#2C(T}F zd9<|yQ+0HEqo!~eso>aF(7@LXaM`Z?Z};rH9|Y_LBq$Xla*GlRGMW2A1+*b?MClgz zC|9bcX{NpHAY#MuHosY5uQ)Gw)!@g14Aj>WN*`ipE)(C#AJJ6Z%@{0CyZ@;q(UB^xp!6JY&z6lJb7>7<3 zFUYplaIZDOTTW!lfseMcti`$DCNTG|=22LPh^(r@xBTMKakTkJ*p!?a!J>P^v!Z8A)*f zgv0afNeYTH1)xH~6`dY!CVEhr>Lm}(Jfc3Joe=Z)JU7Mp>or7(adidQBpc_@zd+OF zTWG=gA5c#vh~^yLUdXB-_|YIov!V#7x8#zcVEyhwRXXu4L7=~ao~s^gcP~ePSe$<6SlMWzSGj5 z2UM+nPgHJyuUWMBPK(e{Wfe4?9&(pcED8!VKyDalJ=aGjhvrWU`~^%+!Cp<>N5TV~ z*A;8?&j2PBB;n#7@3@%pZok&o5kK>1-jD8DFiN*4`xV3R7N?k&abY_MiN!1%=MWFx zaD2dD-J?L~_W0lAMev^T&z2lyaq<6)y|;|rN)&&*sXL-7j(4R0ttQ<4(BdQEMrLa! zM|RJ(M&v!x2i7?D!VX7b$9v|xk8-IEM>Ur(iDfkIs7v&++l~5!#F!m1D;G)VobMAs@`p+hH5*lKZT0i8a0*Z9z%4Ooj*a#mVt-CWl3jxzT z+7u9Ft-iFzQwb1@=hqkwLso7A?&tGSc( zr~r_B_`(N7-T=o=1P^nNui{L5hko)nsf*!v^9v4eu?`j+o~4YuJI3YBvj=hn=b!{k zdli0-K^M^n76V1Fwri0(+#)S!D&t8WW`FgTz#mg8C$H|D6^ju?r^%*lW5q1v``G9o z1uzJ+L^-cIAX5Bcy)xFz_Jlw82HR?8I;D*!OJMme!ZLT|>e6E2)lSsINyJ>qke~30i&EUi`ERlg0Gd-+&K*o;YR=h&lu(<7yuWul--rL^X1pY2mQP4tV zr1j@Bm14czXFiYiHf%o+Stk49(+!Yn{!|bl;mMPvsIwV;z`0N3z#XuQ;`1417Anjy z#*5ZGInd7bwm)?D<*Ccpi|(&CaGoxko_NwC4GL`Ba)W2b>LXn9-6w9JETLlF^)=bhmgt``g@ zu=xykazMHSYX8UDD_T>B90eOeOn?OB`aM#j1K|Zx+MYJbT(w_m#s_ zT#f9Av22(7=ikQYUlj=)+W+dbTd9Q>#4Jre&;RvGilweOD#Mm^g&W1n$!zM6yMA&0 z*xPrs!&V~%<#s4?@gB{C)IH1Hpn&A$oP>|zS8~Dl*KbN-Q8c&cHUE4>yOzVk!?H8&S`36@pJEKpx0v?{)N9_TJgA-u_k~mXOVRncy zCnLpR{&w8h0)>6yXeQkDp}*#4!D!oK$GL~Uzo9)HgS_i!O=2*V;CYnhObd-2P^Quw zTLmyGlv>+cJF~O*eZ%>s4Vb5TMuKL!Q-?c^ZjeJ4hduGNR0n9b<=7papVRC|r-Sng8Z^MEfUF*a&!e2emmOD5RLE}yU=L@psUKl}! z-1I;>#`K7>lU1A)FEegw)!MqUcPVl!=;%gVL)}w@e}%Fj`*M;0H@DHhkTn0jy!#J@ z=szRaION1M`VpN?Nbf2aqtsUQMO#jawK88@E+8mB1Lc|kX$h)mYSDCD6;+U-cnOxi zd1(3E)nlwm7kd9xI%>9yryVdUGsY^y3xitse~0^qdl74Dl9{3%z|T9Z zK4aFZMggdUzrd%NzgI6s%iqJieP4V8+y<{hiwW2ayQAiTYm8Z3%EOx7GYNA%n6jQc z5WB8jYaNvPo4W<#P{0cwav>1xA#bx0AD@(p1hwpofZoVuqs@gga{N-J2!Pet*4&hX z($qcKlGMCY;0%c;CqV7d8EQk0En+n^k9H79F1s08IAotWMlv!3&7_=5V?hbr*Wiou z;}FOjk}YTV(b_2MRnQN6em(@hdLytjBbN628sy<=2iN+?l&8C$4g;7{#JAed$oYOA zMrh~FpJ^8ntl_l2Gs-Xe3%0Ej=3IU7zdwqaAs{dQeKIlyI#M|e8IJUnU zY`J~@6vvi-VWS{nZ-NTk*k+EtIiUHDBDLna*Nk(R!PD&3t)x=D124@E%tn<+L}MWq z{nRbu0jjTK&thyaI8^E|r)LP@o)AyB9<;nw46oq^WQ~_#@8BoP8JVgPhFtYt4%4{C z?>T$FnD#XX+AoMHe6MwY{6K|dWFx&+XL+v+6J|r)^7q%|$@9IYUCT1G*S8K8IA7`g zZcoXi_zar%FA3PcA!BjYV4)2X1&mU?D@R=K+8zJQx>~x+Qs6z$7`_%o1VNn~Qe!|W zXN~XIr*EGqzjN1OUmpM1v>e*Mzc`q8nRR9UYmKY^r^Tk}N$|%UpW&DYr47WWx%*$b zu=TpI7=C}dR6RN?o&PBK3(io>Uk2aR)jVZv<-jI$ik&s=w(I=pD+NHq1Z+i;xjtZD z3v=|=h4`HtYm9w82D$pAQnt`jtJ}VgjFG)C=k~o zDk+NdjO$B?(VzX=pZBC`?%qHuoYAv5Lic6+0H7ssfmT`x*EH^Ux(DNc4VVlGGp7$! zxPIYG3lW5IT{phAhwd26K44nOj*AGeKF8#cJ8=wi5xhTnOvd&O3xdWI2sM2x2Bl$X zhug8325=@ns&(-P4>S|JTB2!n_xpFJEH$u^$9YqcLb%98bh2k-<)=TrB0XR2K)p%H1)}dLCX3%UieW8WDXq^Pp-h9>c#;Dzb*o0akTb+S0Gh zHz9`wzePOu3(FxwjYTPVPy`S2)b=E9oeWlnrNR5e0cPn8i>f|}_#l%$8&c28BN}r+b{@F3k%Rw;-VzoY9r)O> z|DHbny-ru?$%CQzg^mLk!DcdgID!d8JkD>c0RR`sTw!EuCOF`OAJEM5zEt`AT6l@dG z{-RvFl;f*isqw6s8J)!NCc}NgT#4dzW54SOm@3NgXU@D^!RFdNA0VJVV2TXe%D7`X zIp(0Dv}IR>8@rbS);}<6bPsXzV3KRBTT8``?#YWIS`F+H2-Sv*5(q?tgaksp@isdG z*(kt{5K20VdGxOr_P-0eC!MWrPrDms-h6g`l>-o`Fv>Tpgmt2zhnH)5e!8BY7=O)$ z$!FgQtw*1RV52cD3qR68%m4B8B)(Dj=Z86D^WLfZPAzb9=xFOG!&{gfVjJD#zsgS4 zqF^srB&gO*j?7@^7iUN@Z=2svg0mKU8_Wr5qvzRpyCd3R=|)WN7P*p?i>Am9r?Kh> z9N-qy5e3M~+b}Xq*rA*QsDlpAc~3@$vPEmr3(%>OuCOFSh=!B3T^?>(OYXbDb<1a- zqo4UyH{ZK|LaCLK)6VEyW(X4{F-SeuzPbcNj=b<~OsDZK2nyWuN=mnIzlVR^J$AR0 zjaPRbJsjl##*jc)ngUDq>Ls;6krPpvx9x03O*ry8XdoMjgG?I;u8NYeiOp-rzdy#a zjm1?{U;Xl0@AL!68#M}yqQ2&|p`zZiQZ-4B-OEi%Q3CF3!pragZZI#1{k!CZU@>B+ z015iHgT(;hYTcg)l{e4y{M)AxLX%;jKzwP1BkmujAIVVqg)Sn-_~iyM3KV1Mig2GX zz#w$AKyK(EVxl?LASNu>^V@ldHhHUF z&e(fiy2gtrnH6vln9CQ!e)pw!4mAJnpY9Luv@?=9)SBI|R9)`hU#z|CQ}Dure4)F_ zul6K+e>>r|PfP!#$Dz&V#+5;T?)JU=nB(}%>?p=<8iYb`P2;YBv68uZh_M;D$HvQg zx|^j*fb&qc$+O=vv`Pmi}T64EiKJ6-x`VHOK{^(3>~Sztqp$3PubwR_aboIO}sw zv9A&*;k@u_sEGpwU*$I#B~AVs1Z`8f#%-nUGb141+LY5kxDp;9e%P*}y%c}q-T#Ph z2>4g!2xte<(9;4r=2X0er2=1JhtpSbZR5`OcuZSTZ~)_Ir*jtNz$>kn%u0?};zebL zAThaB%j)s%(|=wMZjd@JuqthxeNDKP-BVNad-h8G00(~-#Zu&Kux0mRuxY)q2T^2( z^!3_4@Uj_=0oRM!{jo3KZA@#k2+n(VLv|N<=Ipp_`9=m1*PO~d0nt*Hw?#aJP3E>J z95?}UE;<$J#SEMm~8!BeKg@i2f7MA@f`i2gwI_S%bm%C164#8 zJsbh(kRRO=a)6MY;SdhYAGPN}NHD2Ja!Q7Zy|)3Qd>?=TyGbm=7c{UCyC6EQ{D;td zB^6XBT-53TW8RrL-I^y$DJHA|hBLu>0Wdz4;TQd>yiAVIL;&Z$%YF9ajb73LU-i%s zaC$JL2B+i`)&T1~#Y^SVDhDMWOq;U>lJf~C$i9B9sz;1Ae9t9rPJw#_okRZ?0nAEB zIwYU=k*+3(3AY|>RL%$W7A@l!g&E#@O#*U0r6eQi!@WAG(V9y;kw0z=CORTf{`)eD#-Ynx&)=hr~DouiQ<#TC}0NBeY74(VgIPVTH}R|UwF zdj-gimE(&)%CbzmA-FGq^2!;EUkt4?3YacMqrpt+wi4n9HGAY+i$@& zv{c-GKIF^53K}q9|0DPW3?nlCeavd)L6C3@+iMs6dvPm>nyK8uB5j15XLh~2OpWBP z+F&E7tJazC7ri_ivL}y#L$z2pqw;(=Is_juv;0f{!o$w%?&bK=_FJ*5Ds|$KP+52? zP`z7L!(v5WU@1H^Nly}`a1CJD1UBV41R{`jzxIEzkESa99p&3EB@29)t&#dg4yF z+fR0cpPjiAsv=&o`tCW`y|nMGzOg+(HCqG_Rf3okJRfMouZ??gX}bMH+GTC>UEEU9 z^WA3wZN)NuJ=s$-l;2BVdrS~krQlxRmq|nL^+g1nh{2EmRI2t0>a}0@>QcJHXeNbC zCN=J$Ad}P>2W>a=%`uNbVF=)ED0V75iJLfMnu!!Cm+b?IyQw)Z*of^;AV)8_ z_Rx@%J21qzjEBth3LH`dF^LkbfA=c?fi{ zQf3_mW?hFS_dTpvkmzMR_Ax<*b&4bm=$H1CP|DB=rb%8;89s5?a6G7`z6_dEF+s#6 zyN~o{3*?Rh0(m6`mKqG=&xz$n-=Tm87-i+KaQR9TPH-cR(=q{*RMn5%J;c)zNgMO; zS#DJC)DxxpvSb`Q#m%$vS$M4L)LuY|?}7YskBtDf$%zUX`jp?cx5KVe!Ho*;9P5s_;8n|%@4*M=oy@K^BV)|uao}y8Ld!W*bj_d)~0zD zwLpEQcJp@BpIejqhVJ%1K60vv{VF_qPu^o{%`h(#l^aGd63tLe4+p|D6!Li+;1nej zPVj@YSiF6AEgYSRc1dynKn`OIaPfm)0j&;-){_j&=~GupV^c0V-d+_sbW zDkP8lEa1@erPGdkUwRBX>@KP-2>2e2=)vQ(5wMm6Go%w3W&estt!J)aX}18|gPl;A zhHs?LG7>PiCnM~cmO2sH7T^JTUOYbmqo?7j1-z7Z>sN=KN=7DjMwp0GzKmJs2*|HO zwzG!GyO*qL&qYe<2FGfI@cN<*ZJDwx>p4-25Wu{Elc4}?ofbrq)JqyF375#|d z1zYRF1r{5v$ROS!>Yay6J^WQF$Zo^Fhe zsvd)*;MdpoXM&FRNI9m$i=i9GXX5xHUgC{z47UMl$v5>6fB+WXqJKh_(I^vO!Gn8sNfXbKu<3!*Ewh{KgOH!jJZ@!r0(q-0P~hNaBC|l< zXu|g*hHtCtSjD~XZVXrDU#_?n) zB>6VsGpxKYk`6s@c)<3^Wrk98FVfi`3q}q<~2nrD1@-x_X zEIyas($693Yh)m^&0Hl~$(Dsjue`?QXIo?ryvTV?+kJ-T2U7(=h%(o{88L$W>wOor zK0WE)KwZMh3HI>W%-~yE1xO_$=&u_OFN~z!+Kq{vdLA=YfdHwK?@!oOj-~Z<`tK5m zQ9RHXV?r#MC+|#FFmXq5p8l{6z+Wv@;nK0OCKmK;ZB_8i?Zu0!11J4x%)`KTc!$<& zVwV{OFEfoxhZ!q4%g@t4ZvfAvGt>SN{USf+qB+K>kf8qZI@14f!dM;{nrf0mt|%qt z!?|wiQVH_{SO6wvbGFSLaWmX|llCwNPQUw;M~B9uFx-WO!G*08 zzn5$K1Tid)JT@oCP8-tpW0L#QcIfOW>-+%9=vy^iI@q!1e%6Gidg_N_dmz}D0B>VB z7<9y$jc^??fnfCqa`9{c(sUmz2I!%gc#8?t*WjGfpGVH#J7C-i|uCNJk1wj<>~@cKKbTFOQEeV0Q2T*8-qJP5c)H z5EMZ1nWwma_n2JZLh(s$M6Z-Yqr#$>;X4 zqEKzoKN2_4lhzQ(L&^BlcR+^mewx>pv*&7Qf z^hJRIFn?D1ah{p(Gn59avsQ>O9bOMExm|Xuydju*#)b9(Y=8jfNlR`DP}BmIgvLtnJH$lmx@dZvbQr(k`0eHlUqYy0*zhoh2~ zjsK1N3>CZX7%-{)_K4)D&-l^m#}(^sG})Rvz*(TmEV{$I@}e|!RE6-`sBX6-VMzdN z0W28yv2e4J$2N`1dL-UF^>JX3v(lw|&+Ds$v{gd+T7*I<8-V(;K}696*pbsRYD0!J z4CGec=keYclz*y&Cw;>$d9!bkG+^f3!@A|+uQ}Q?s9?TN>S?A~W`d~{^?i%C8&Qg0uT0$Bs>VQaInocl4&16G1m-?J@+?if4%wtf;O}C_@dRJNV>HK zC-_3*%oU%TN9GAVeY*p!m9e0(SxJ3X`us0w3+>pi`SsKe5H`ysi>619!)NhBrGpAL zCgJja7oZbAuMNBDL(EUzJjv6V#bG24LyMY~+_n@bzZQGSXvaiGirGXPTSfbG>|hU9 zW(*;7@8_=P|FGaG>-k;pV2(}7_4_L^Xw*wvjJ2|rra3!%3d@A!Wnzn7p&;v$e1cYY zANxF*Ax#r3uy$WbFgSMRdiP&Y>63*a>FTp_$CM4gDJ%As-!w^5q;O}5IdMp<+gE~g z@ABkx^bYmh%F2h+Z%-aZA;g-2TATkN47UtR9ojg~89&n#jJIH*WQp*blXQM#H%pL| z&YKDccoB2tE>M@w!F`PqFrvUTat&CxfS3gi5<)GsG9bS3tOX|eSTlikTChqmL-=QQ zNW!5Sg}(H*+m^_)XFb8MpJaApGVdSv<=(6&J1Lm$Sb~Wa()QFU@H8IXo#xFIlN0_J zZx(^9+}p+j{E|)ppV|dDE`nfDsfa2B5#!eR49#~M*LCL4U4IF^wl6cV*qH2YiN zla|Z_jsCo9*_PsY`Z;{VH^+B|zTA$h3m9{OvUkIA*PEYU-(>Yyo|mp%@?WWnP*yk3 zrH^c8e5#aQw*nC!8`~myvY?2xu`L-Ml@~Ud=)w?Z9WfbR(56@7aU`DyXU+0>a>9dBd##~ zoTjDkU%M6%GbLL_Hda;8L7ZATvYC@pc5x`SmqxiSOzU~IoV+GO1iSgR7z8#mr z&pG+AE&$L6x?!56sIB7}Y7&(fNU7i|TV zM9sz{eSTVMwm{hSc#_Xy`7C&{n@R+x%hUz9 zzItGWp=<&Ag8_){gWx}p_og1>#}-<>Z!+Q$-S2@mLU6CRaRmuxVi3$I0b?%vyh~sg zB-n>^&?4C$U%;jb5BL>gRB2F=F_xfs>ox&ef@TP4_R~;`@W5`c;%kp+5}>0<&6X0> z8ilEDPvCLI-{R4}ho8{~8GA{#4|?a0TtI($wO@^mS9J{MttEGmWJ8(m(NFSraG z3B!v|q$oepJKL&s@4(9!Q`rZr$GA#u8`MWS>ry;;Z_xWUK9~LeB%9h$Eb!JC#*D)v`8@QfUe7nu+V&+Gk*2>lkB;lt_X+d0=S+$ah8wks?YgON$zp23Na zoDA@CKfC4>CIti>;j%C9JAK%)DS!P6>@MojyME`-Cw)C#;XwntTae-WZ(Ty>B$|5@ zoHXEeO{6RC{G#LrY$+s+BsLRmt`YbnG4*ZzW===y_1#+%ZM4K8h5a;^-0_YB_8BFE zFTD=Idf%&a3Z$2cs|~@>($aiaRykNh)kmUyVu1#@4amZ<4NbU#r`z{0j!!a;7=k+{ ze0{udBlwT!bG_L!=Gsy`@eSJ#d{eq=T)K{SR3GE^P3vmQmwa_-%>T~)6}b!7)Z#ZE z!-{V4ub*;)gqvG>8riKjRT^2+S!A-()AqqIs9MKrSSs@8gN_~K&!O4C=DKqKhu@M8 z*UGi#;_J4^KOTMBdDnW*HHzod=^^Bl#Lkn`gGp~i|J;3g+GX0Gs3N_}#i=5F#9~!H zYq#+7$qfkg9(QrL(PV@?8xcgwURDDSrg!&gi=CIP(4%@5GhMwA&pX%PMF2A6=Egoh!&8B$Wpu{E~DO2?cJ!lC1JD0br1 zAvJj0@h+jBaC^sDRlnJ&s0;V!o>X?O|5`;9j*tBAbG#IofBCiDXl?!Y{X?FAR)c)} ze0&CKt6i?tZsj|-qnaOBzglB_4qD|n3Y)NJEckN2!dpYucnwb(61c492(xl9iVUk>qhsGpVmnq%r6JEj?E`XgR~6R1K~?Pq$rI@phqWx)-Pp6==Y5b8Ck6bTi?b9)RjFC+cCp+6CW8((xuXMH4Ba9nG3f@k2JURU$LD6vH0Le;f+d5 z{FsVOpOhH0`RXq#LszrgZ7cpXPtrTCB82`KJAy2PP$cdA{`O5;=?8)CnwpE@-YN5i z67hJ27_3W}+xW)jTg7YcHToqR`YtWOQ=UbuK5cjamstB)?UU7FZefrOS>u%N^xh}R zcZDZgtZ|2o$k$9!RpG{kEb@1zn(fQN@W9E(abEFWFKs(`@jxI zSg+W9%O5cb*sOhdlsCX3t-kvSE}pMiVEMBB#=x>;=RhfQ6=-|9V(a z$FVv^y(-4UbKjrl1|PnCy&n~O+RYNXB0)X_%lBG)lph`LZ3L=&nRMbKaccypcN__& zjy_hsnLcR+=JIh>!%~CxS?NROrV0B?0D6Z(lqD1KMz_%GiB~Qy_*6xKGN6;49s|}>Cl=6C zXlS<-)rLpu9AN7n%odlvS)YJbJYa+;vjS;0X{DhweSQsW&xePr%}b70x4?lNz2wR)pCLMhDQ9m6#Yq~rq@}`5oI$y=Kj&EJLlBVnPl(1?>{i3KOpxzxy8pbpVKnR*J2G_ zHCic7L@|3$jMFdf?aU$w;zqjQHyOGwi}EV8xbZQTaP^%Sn~aGqUz{fj*I@MO`gpB- z*)sA?quYGoQE=OkUXQctYdNfDPm^*JOhx8eewxJ-jQXqUKCfEidLNv zI=}rbAkY8R$w(*|g)G@*t|qBBl(Ob-$=?o6*8FthhVS9~Tmx^OlDP&dpW5;-3*G(x zLa671*u-zKX#KSDoBV5xq9Sr)0lkS-5>$J*=31ygjzDujin_z7ywrkXPa}k%xOPXM z7|I`u=Py^t_6|=UD0^)v)p(Z%3!cQAT;_6M&1q2hx)?b9Aa$y-?B`#JqSX2O8R5ja zBT~o11Y*Kp5k9FFR?jV-cPqKm$p{fjReHKyZhOCJX;|s>Fgt`*>Xvh%9IK#w7sgs! z2l?jY>1mu&onO~;Z0GJ}I)g(n$F`>MxT!?TMiw(GvfiVi)Fp$0ZmI@F*`gM`KG z+Ue)MzjO@r1lXT`G%`L*@t)z(8p%t#p&2HSz-N7sCnqcIRj^E#S?+^Ti6lyDvrpR^ zI)WxnjdL|x&uXXbm%!Kz{CaWPZs^x_jBVFncfo%;K5Dr?Hz~J?MD)$C9`v1?RH*hv0)}9 znBO!Zra6GkZ%;jP6#%%q`xg({ucBs;T2DquzER|*xc+^uWB&5zY~rWcf)mg$_{8fT z@7CBv%{3mFSeyec>8T-Gv=Kj}S74DNi8{QndpY}lk#=LnBdK7QDccL_GZvg*=^Nq! zjb-c8*gJR0$;TqH*RNRwwdEjdI>*A|&8!g_HEV5(k!Pp$b6$SB-*eEy_eo%dM{U~` z^8Kq{=geOlhbsJe`{Lf2k(HeH>;}D)aMA8op*co~OaDEQ>hGnqtL?1ZM=`eGjkJvq ztPaH~jWzt3@|VJ#aS7(Sv1U@;bj@;70{Hx#R(qwWh|(h&kT+hTY)w%rmaT`S5GYZp zK^?yA1)TMP!BV3HeCWp5`O2tfm#IkTkp;gT3Um$5!ccVn0pfACTh;zMecfnV#|O`C znf8hP9Rgz;Z`%{<54r7M8D^y{P57}Rdfu0?BUBpJHEZM>A~kCu$0MO(f3KPp_gc!B z@>S%WPkG@Ux_;H(r#+)rF1}wwfe3q#W!ZBI)V9ma=Bds{F|zz;fsekA>|;GCY^Mk| zT%u12x}fTAsz7b<;xjS-Y0u0G{t+>yD)S)UD5w8RhO#yjNM{rF!dnEVeYx zruX74AXtER(q=5-`@W5%k>_=tDt2sRFyFllR#ESMT=HlX5l{ZC=6R0K^xFb-c{J^T z5$eyEDe9;EN3pZUA2<|bd|NMuaX3LRmBp;gI7xw`NgjoK7aJNP9WS`yUH3(bYAx>E zlt&XMXX5!`WS~JPCpha}RGW<8!`S&%%Tj}qXD@MBf-<`y>>PQGz7GbSck%?sQl;3M zkAi;~TY%@(gi9nmvY!VdHdQC-3t#ZGV2ffP>N2xem~=Att#&~}Uof3hn)v4`5xf+e zVy6=^(yV5!?O+`H@D+%?p<{Az*Htvq-@dPdr5xC_VL`rtUI);dOR!`Pn`)F)NUs7ndFmf8AG4*B`NE?L*^f7lLF zAi8uE!}a&#$O#-!B!}pZ2=e*cRoZ^)4Xa5oN{c;+%H8Z0$nKfALu~@IIhVRQa>r9; zE8H|r^!oVd{G%%dT4l|T=A(j~>jTXImK?hNwK~Cj$TnL*JoWf!(>|yn zNR6zU4MKl^p`E^e`Kq^+UV`ZiNBmLxvrm8WEoDV1-g*~520U^#vLL#Ha6;@Gaxpkd z(651hY_Al>evlEA2rM0e%pVVTfAESCY3lQU*MptLWoJ9Bf<@L*4Br_tVt&al?M07l zmSPkhe9~w@b%F1PNl}g(A?f;uR!$h$u^U(9$mbJ4NuuKQHzF+{H`%{atYFB#I+eq2b*#WA{$8S>wX`Y6 z4)g3Uo6QnFn@G8vS*xK3i)P3M3A(a#`l9ZS7X>ck89vIGe&(RpN$UQY2QpiHo}a>L zpbiDfHh$H|nci_IJuNRZKPChk2VP?&+2(QdYTG!IrK_Mgb_xTQwJ4sO$+ind*(5=% z9`X`f8%ne9wr0*ul#e>N0+yd}3HMJODVx@}zSk~teGRX@jb~UP)pp|H{Vuwc&C1^4 z*1Deais#pyI9PM$1C<;OU{^kA?l5niv%#6xeb%;hF+MYC^6=O%k#3(a>%M~|(-Z%` zP{CS%)t>b6Z=5#xw=v)tvhVrjr*w9clQ#kmU*Jj_eE*8|&X&Amu<(Ncr(p7f0jY0F z-=?3{x^}OVCtG7M ze|DcHD*oA_B?6Dn-dhk=`vrJ-!c7+ne0dBMtupP2nRHnkN>5svQgAZCtbqu43OP@V z?@b@+8K9pq$Ty!+s*skUSg$e4A3@0+5^0Jg29Os+(bvVudQU0y*|C)6i^efxlFkOk@f@gjR3-%xbHN-&E%oTOXZDJv$*le`w6_GY_lytw z!$|v%2D*LPAh{$J9BYa^dcpqzXVm$8(PDpVJ~K^^RN{}p5g(qQpu@}SmZ2`ej@Lp> zb&Z9B*E-rx7|U(#+l#sql)u@(__n4V>!mSYT6KSGk{K9&uW}sO z?KL_BM2q>K`Wa0|P$D!6yxWIW#l(x76MADM+MijvJMX88$d|y*fu0S-~?T>d$@$I_7v}}n&QJ0(RL`ZY2RXhPaIG8Lk(l^J<3MTWbjDTlK5_dgl>H#xFcVMN z2CVmtwVGHH^Q)fKUP~iTPFrc&+peTSm)d1Z*{~89bIO56dqZXmZBkx0{>mGG;qZ zTOoJ1PD?T@_e3;kiP#7n5o#5+4$`xUpdh_8@^&=ldcL9ocwFUQK?;E%g{Mj1fQG*% zA*Ett==|j`uBdy*D-TNcRji%34(Oov88bbL0KXH`dO&duO5Nt@Z868(-+y+Z_bIsa z1tNl+Bftm*ATLry1}=4CBzC%z|4q<#?sg| zV=YAXq7bqSA&Tt#ShCF62bEo9Pj*R`Lbfb}vCkk)O23!Sb>H9XKKFI5-#^W1j&nMh z*Sy}(=VN^yi2Qku@G~6yx98)JAfzNgAz_~JSY)c>;|x?7Pprni`ZY^XG2YWtb{VY2 zg^RB#Rqg+iGNfv@bNH;4E(05cHQN77mL%6v*Lpp8y!+)Loi!}b1bJjv=f6LduxU6k z?xgreW?3}`q>;otYGA88q&C-x0qiC#IYJK?WCK~eVh2v=Bve~7og}E{-xnu9U%_#) zWF-xFj_0=Fu$ZveB{9Qf)uJ;4&*S6v&K(K~sn*Z#(U_;IxmlgZ#2EkR3&{v+Oypnn z2o1m@xb3Mkxc(?)gPe-Rs1=}^;LuTe=?V$uBCF~zMA248-Tm?Zxy3==r(3-<>C`du z@4L>Dn18@@oox6jvbXu3;F24(`e)XFd@PDGEhaeIwVo|-W>7-mk(~&0>6744^1Tn& zZa;iG=X{ezNKpU!joU5ODg~;1A}kq~twg=gbtmfKWWS{9R^gfooGID0Ids0dzgy%M z%B+3%F^v7T zLXn|Ji$m{CA?ZGy~yn zWe8*}H1((l0}zS4Xa)F`p8k5TVXxcD)Y%kIBNx*fLu^P}P^WDS4WFU6B@Lt@y3;`6 zHge@tG;mdd<#8Yy*CUAi7@V05%;H%KFMRYzo>(f&N2DXT`y({T=#_+Y73*J9ezxXI z`e_lVAo&vI2y-t=THqo?=n1k&7*wJr2MVi9IAuf1K*Enz7wqpzm3o1*aaXzl{cULE zAHwqbZz*#alN2WU#HNW;G|EzkKpK)-V^?{^^~OgA{jja96$-&jj?-@Ml%L25jIb zViNu@&mfhn0M7PB_uQp&LAp|S9;BW4DIwW(S<3JXPDJN?=P{ocH;j@NH;_;9Swp8i z?4*n?>N>Vzio8jJv9XRrLm0b^* z9uWlPnLs@nMmN6PXK~2*l=(~)Tck3=>A*{JE@x*BNB3V4YrK_LJo+Nue3L}oLjPv=eq)l#1hsAP+&XS7~ z!ON71eho*mX^aU6vl(3sNBmS@2Pe{d3&^0Q!I17uPXrs|4#*41JJq>NupLqp4)~K1 z`aoF`XuI7k%<9H>UHU*!yA*?iQ8Z`_TuB<}$I$`9bB0bqD)KwV6R6I6Qf+rAeTq5A zzIJU}ngv<{9KaKuuAB^gmZE;$j!TLF=d(Q+qtj?I9~*d=$k%#3-G-z$DaZEqOYPa{ zDLQ-1ao@Y9XJtv%Ol|J?l)IDZQT^BChJG8}0yQ$u14V<y9pJ-$TayEYCq44b6 z-%!2BX)K-qW%&4(TWrnZ9e*gTK<-YnYqkc3HlN~bz+%ks4KA$UvT8vN?|jgC(R}MA zeLBc{7KDI~YQw@kTu-W`>ZS(_39C7eDSZ`Z%Yrmf!AD;bfz=IyAA;`(uM!#gbn*{K5qLXp3Ob(W2Y0={UnWOlu~{A6n>JeRx> znS%VKT1}v{d2FNx+Oq#G%myemxPo;IuQ2^*;s)6UAu+v98)wGPX3c+yr?~e+_F>qx z+DC#$+?9NuFL$%gJ{vHk6~uO(9FtndT6ZmiJ)P+1rx3Q6xObGlzY$W+y?|r3F#7;i z4z^bv+IZEbHjsTS`;FOcRZ9J5@0;Z~&DoVrz8fzYE8KMPO*;3o0p4o=PQ)L+@|wrR zD9lI95a%18%lSR<5)W+BJEl#&CAelX^=F4KX5w@+M@2bw7e*akV;m6UdVZ4oK z#Z?Znc_F4kIv_sCF;i6sCPGw*1v*{OUX==7x|rIJo+t9VnBUrau4Ya#3T80q-9H9W+|pr`idl`Gx*vyjaaX5hO8Hhv|{qZZ9dn=ptNXRiOX+xDam(0 zHjxOX)|c|K9jyKFKb`x!zR4M)$%v-;U%vt;&l&TX^cr`WyE(M`seO2xwGrZ-hxqUo zBf4=TPAEydqwekvB6<{S#`eh!w$?UW#Wx4b(3foVeU~u=H9NZjrF?5RvqqBHs;m3B zng8v@v1#8x->tsUJt%d9E!PzGgyGz8BCYP)j&FdS!kc%;cgC~(wC2u3D^Yu~%BMVy z@DhPIw9EsVI00CL{rn~IQ9XzP_pMpJfCLwc9w^Z?kuC|m7zQ03OasJlaoUS9!kU4~ zv>wht@*Gsa6ZHP4N>M}Lt<|zH$Sw^_l&Fk_6)lpgz^ttJBww5sJ=uQ;}I{ z@poEWYV%Ne=ze*4AuHOh?u4JH9b0c;p2GRdan?*8{i#3vRIwFhAR!|rGtf>@jx z=PP(ilHd|s4rQ<;D_kPN$2ym`?ybQAISBx4ciw?m=0+aAnlT}YK<7-kV$GK_t}mS@ zU7F^N&da45oEKpN|1Fh`5P2z*m@e$4I-ii-pgyvOUkYP0T3q?6{gbVqMVwxVLi)p@ z@}3jO~wK$Oghnm_w z;K;E$Zok=_bsJI^nxLm$d~jrteT`lzxv#T2Cx{kO6zN+px(rK zEj5TJ$^7#oar0C7D3SsDu#d@OYD+G}jNsY$H&-f$D&Sj%vg_I#xJHO?=9`?PZ92M! zwtrOkXv_t))k9uT8fa_AgpqnfS?LZPQjD36UA}ws(4-5Shp8X@X6YbG=yvn(A3XoW zzik;_E^#>-@w+dMBcXZ81SCn0FL>obc!?82SYUV&pl;&j=Ia?|p_whB*kGap`(ZH;PgfUQt){@4kP13g!awhA zvLS&O{QKAJnAm?kqNjW##)j;B+d-2FgAz;+6MQ^#N;t-$Qp@8cv3jYze72Oarrpv3 z6e$!$1%m@N?dbd-ErB7Nu-EH}%hrP71&6lgBrza7(TB9WQM;0_P&ZcYmp9(o~={KUkUkMYcP3y59W?5NzKqshGnfD684Q=NM^BqY4*Crf)LI%n_TOLmIM-XCUu;+GL6hLxh#w0ozhC$32Gqi6Yh)(<7=drurku02hR_{IB~DtdX?FKa&F zP$eA|^mCB64%KyMn@{m{Aq;s^WDPCf@uyxIFu+M-WN+4gefT;UKvems(s0&o=N>bA zYGN_jPvd;bg%GpJ90jY;;$}8&+8*XoqgNX9^&TQODXpdPt+StAPu7-$lIiui?I0R- zD)KsMfXkR>tLQd#kvr<)GzY%8#+LtDYw52bxw-!v6sTB?3VIhYPJ81yzXr7J$VF*B zOO7)d7c+<(*n69PJ9=3}MD}wN-)kPh$W$6f?e3fQIX4{-n4C?~(m~K7rKEF^bNrqpjZG5aX0o+jLpf}f?9r6LJg?8YWq-W71OFk3=I zHSdq85krAY>gX$}B-c^6SEADWT-DyvSU6GP$tFW~UgJ#DG#3l9t}%JXpLVC-%v)+Y2rd_Nrj)Lkp9M9Hy=4~fRpaQytZ=;zE{SU4q>L>W7`=fjTH1No?X z4_y8{Pl_!)(VR@@HMchC`B3FPWuOa=smM}!OG{n`2m92kAoOBcr7VZA>E#_AhO%ba0oIx_XVMZ{grEP-Gy{CZs=YM zQt+gbkOhfnJs=83I7c!)n6i<>nj{81&w?gM0R{6XJ#6pl0R6*x@cG(2+eMIsdK>Dt zN-i95GAB|)FFWGd)>^_ofA?hYplV(3Gid&mMc88KqzSJCeH-A26?h1yjMb!O1 z_%IVwKd>ZrhDhyxTh+JjiEIpRYOWFv9k_t}{>%0^1)%A=&|~@mb>oiutB-@SR08XR z3r}nAS&XF!fFWpA{N_epIYVBFOZ8`G+_;&3!C)V)6}IW~hhDJwd25wIm5AZp`#*3= zE~6wjhu$Z#<3atAm&oXiNT4Tfw(CtpI#g^HXf7e$Lx37~M(e|b!~Yn-=}-)71Jwg`p(;P^E&C{X?S_|C69TtuY)3-w zD@)GqI!9IW5=jr-G37$;b%O>&iaeDy6=6Wqu0-Mce%w@B5G7#K)taHlZW!56TipeV zjkwI;PmcY^VEoKjHQ&sQ7Y?$-~-()hGt#%IODUhY+f4BK18`6vV3D&uHZ8-vU#Os2W6!LuX7UR>5#)I#iiX}SK$ZsU`6s!PBPQB<%!w#Ok z6`8g~h46D_2yiM1@YewU(vQQbki@Q)Nw%dR3oegOo*PSmbiGKQTqm6pk+oxV@d{tr z-bn$2zvckggP`Hk1du7_=$uxv>k(jYGKkaH)|eYl;=IfqE7Ia#Ao+3+g``f^)QoY$ zk4Lzmg_2}L+14)SRIFb~uM*rIQN1UUNBNheu|E#E-?M3|U&^?`UGdOSsBf!*!s=r@ zg3s;|t*2g$+_;ra^{KirhOYBf&Sjt~u7T^}8TN<1AO-xj0#` zrAOu0{WiqgMh@Txj(3$Zqyp{`9QcEHM_S_crca0iMcI#{7W}0!z^-Xo_C&1`wesum z-{@Z_DBcyK*4dN_Y{|D&Vo*y8F(NIP=m>*AC~+bKk?;F%`TJ5j%7Fbe)qw@64dZYO z0%IRiKcoAXsgwphRCJ)AJi<8Z+b@ntJ$MZJ^!?loC+2B&+&!$6*B15W3nbh1MSHhhko{L1#EXiQ}NpyAk~X|e^?9JRo(XT&tZxHo%dzQ zXOdbLeL3d)S49WS1KdD|v&RtLWpN72}_- zLDJdIIh;o}?ZrMzpuZ6tz}Xg}RDyQPhxLy~+`&P2soL zS0+Z?j6{X7drXkOU!LqOrEMDgBQEY1YY=NLYcBG9EM~$4nTQJNB853wOOhV8-PAxMOrYMuI1_-I&HM?Gw0f+@^~WrcNuv0 zx=)OkJ&&iVqCoQ~bB~7!+LFZLAgSD8)=Czl1kk;3Cj=xo58`HofYu4@kVclUIS#AO zA0qH{I+J!~*UeOKJL3q_x&N)flS0Oo0 z%(gr7Nr<6M4a>gT+0YE?P&UxDf)&l{Y|H%gdSx6ekGXiTW23>KeG66-m&a#5TlBCk zF}QYa%Vu%Kx8XTzj5I)BCRl(D9;2*aHI*AqL$>ef6;c%knOk5@*A=ATt$$3ryb}dV8J{@TIPs=R zRbl6F4NlZt@8yLj$`_A&&TKIwpWrlmS%8}z$99x6nj73{R3L@z&s|-nt&_NWF{{-O znir!uPka;5r#*U*zPxOS{N8>ZS#k2^L(+9|@wcg3mecvc6~$>4?t6C9wxgX&NNZ?{ z0gT`oP-~;Baj32K=MMLzzOz}ZPa&$yJfLAb+Lu*~sZXTo{V&xPcvCyb z^73}9u97RMIdz7V8)~>M!r=+5SrCGG zdZ{-vq{-k)_PXu-{tRfUtVB^heh8gLzvLpWj4>DWLy|@GUH2YN7iYd))vS?YsTDQR zFmeTmz!GFp|FV70_}`%V)|y0;7~9v|O9NX&UHf5Psg09r0$BX+uVS{n%Eka*&B=y~ z-8Ku-P!{K!Kn0BJ7;46KD{vW=+ecpH{yyy#_?|?Cryt}&Ym4@!MwgGeIE!=nO^dqN zi!SSk(MruS+S_@)J70bGy+;#oa$u?0fihJnCr#l?G3-u@fgvy|+ph85iNWbsE@-Tb z1M!G;^EWY&N^o#b_4L{{ca1A~&?ZT1#0OWiB6NHDZ6i+;Uz`&_r2TZG%cmZD$50x75VNEmb3wOhW!dlho6O~Vz!s6l+h?|t zYW3Dw$&KhNwB#3JYzXOcLXWuVO=><}ZK^~FF&hP877Xt)?sv3>T)hp_QceR?PSqj* zlXUmA{U6%Dx6db)?wT8GB+!g!#ngJFX0SQD@xpp2hHo>TKT@|kc4^jCwBA$`)Vgl9 zrsfcOEk%g=O8mESp%BM|q{J&-=FY<};u$MqW^OFmgShFjw<#A~BEvr!P8i=&(Oix0 z*O$M~mZD^`VhpG#dh|N(0!2EFIczs5dvX!F(mHg%mps(&{f{zYxRh{dD9~+w-2GCe zOr>0qjph9AKeB6HrXtOXXFxSOg{p@LCH)ei_|FVUKcG#5wIZI% zrH8F$@^Y;hqiB0nSmU>l!w9vUI^;ja@G{`xc40|I=nRX1%s&=saP7^b3!q#$gU2r>!o^iwWU`Oz{M zN}cQYK&uzN;v}FUk;uD5Ub&_Lgd`MI-ZagH7^Q}#fi$GGlGSTa>_h^U1&z8;GPMrh zu9$+CZVK}J*{r=Rq`hZ?M4p2Fm78!ayc{+xg`Zo(;I-@0??SMFq^z_%FULyYEA@Zsm+X+ZROJwDewgI#v&)jf3_|wcfOJLu+wDc;9(H%?nz4r*Yx!Sg2=D((topPqJCDJT(kahuGG__faEYE`Z6|*5PPm7f-6(XhX3VVtg z$<8u?FI2Jfsv1dC#go{v^)a zRDj`m<3q1@y(pB*%0Z(7|FlEey(G7s>raNKT4RH|a(4RZjuE?P!1BTc^1JE{L6A)i z4{uLe>%dNgTCEr5S~My)UA){f1{JG5W`P&}Batb=E54y$Y5;vl60-oJsgoBZeO;KE zujgT@YQlEtZNGO<>icnj$wl%Q5FeC+$aHxL7sV?5?MRE(nn){-EayC(XFyDR43K7f zSl?qOIu~N#3N8frU@aH;$N=o3Hx^URtxhrXGo=^(z{ah)c^0s7#l86)NL!$k(sP2% z-E!53*u&FYw4NtKz1YbQrk9kh)dy9Y8dzT-V2$}0XNHvbldA}(6ohyFrgV83Zj^tEpQ%YTbsy@FW9WYk%$pEK2XkMK5?W>@V1g~LXF6H8HOpuR1^l9k5 zCm|$1Bj3CCS>G(B@M$?}0}qiflpJE)NA^=*2W zfC+jxeKXp(c`fzgaGqV#7-45W@!@Lda?`ze#l%ND%71^Zo(us;G?-fGKp=H_EXs6Q zb-D}^Ei8o<#eu8{LogLKucUDzLjzPLvb*HR_M4m9zi`M5f%jv51+C(RQ&J+&_7^@k z6AGz!A6q|kuwF6j-c9tsw?EmL8&zVa5$QDD5Ba*UU;?P{f#YSlNxCm8UujET%_RrZ z_Yq-5oJM}^mI5WWu@zvVFuXi>vG`nq+kE(5vlPn)<95cIe!bUcUcC@MI1X&^3` zQtvs6)ch?kbVYjjBLB=a|ElxRfYAXxs35?&#t~2dcNM68#38>m`+{v*$|WuaV$wlx z!*)IsqxZ$;XOR4Qlp9$8q){fOB19vROB)Zk^Sop4J+co-`_?|vIvSV zoF+y?BtYLGp$_x}b73?K^2*>qArHbG>PBYgG2O8HJ)6H&@A>+i`&NFz!~-ueU#Fqd z7`Yf+MzAS^PLj3=_U>EhfbW(4&lq3yKA{Ad%j21PXSOV^0;6o8T57`a$0lDEHBdm) zveOmWgS5o@GHNrXTbzITmgNTNY`2_YQa9vl9_Hym>hg5XLy}v*&Mo{tIIc6DY~Ble zqCYv-(%V_t2d%nX6=yWuFi?CLvc5}$5-ii6QY;x0_2PM7%F{YhFv2yG$%&Mdv8>F` z)x3!A{;d9cZ+-P|1c|X)^3O;Z`epNLYSGXc|75Lx(%?jb*afIs5TP98e@`KRAV}W7 z&X5F(shg$!aOb1F95HA1jaA%;pknXzS7Si=Ko7>CDW-kuUBsKk`j4?J=EI@dmzQFa zpdb%({BfH>+?5un07iaiO3z?0V%g8|rH^FQ4DV(jH_u!#o^=zn!}#-7v+QwCFeoQE zk+H9WF+sLA3n#h6y209yukc=vj{YOD0)Z+D|24;h{2-u{B{g#*-Kfg%Uf|vdTB0ZD*S|6opLI#-@c4Kp_lF0t>Qz)SwP1ED?@{3iqnPL;yQXIWfJb0 zovpbKRqjC_v5wI8eKo!L+;8*E$xfCo{zIs5fNBcz>UF~uq?u2ns@E)RJU&=F1&I?U zv%ky(Y3jL3G^m!jixIB<2Sq)NmiRCZWLLQYH>36fyv*NE~a2wUS?>H z6q9})4m})z@X}Ze;1bJlPsu0RtlJ0bYDDUIFu{+JeBy%&!$>`5HwmG-ufs@@X&8v| zk{BIiI5~JDE@-La2xvPK(jqr~?mMTI%8=+Ri4%a_k;;)|1CjeEN`vcxMmn%V`m)cm zd}w4qz;Y}E!4X1o1BG11N(3^DLi@6yaiNm&16NUI!1si)vaWwRJ6%MR9G9ZQZupmI z$xw*BKvz=2M)H~8xkCrJ9NgP+j2Bzn53uFW$sh$zPE!RQ`n|49(5l+~5GsSdA(dSD zeT|o9Wi8;!jL^-34zt|nckglM`)+U`%eUOpofNPCy*StfF7Xgab&Ho5hx*MKRc08p zQi?@PUd3ONP3o;Yzjj!}1LIj;Cf5WvK9yZxpaES$5U;+;SYMEK%8uMmMFp*lnbn;h z->rMMwV{VGkjR91adJIM9>im4Xeu=bPbBDQDL3CTN_0wk&Tk0 zC?j6`Z)e7zWXW}Y_wHtmR@S3fr zxKfkTNKe;#quq7io*(yOlQ=q3IT4JCx(SCB4CTRL<(>iG0d81{2W(~lYavDe%S?N?7P{R-?4ul zMP_Asq8!9ckYWsGNQJ{iI?=fvgkh->2Oi!G7|tA1r!K<}9Y3}l9q?(M=yPLU6cr{# zJeqAwbhGR)%YsS3O76@0+0`gPH!d2I&z;>Ji$hSjfa&}>_z5eo61H;*%P=AwN}vV; zkgJWr@grN+Yfx%(ffX6nRh%lyYwT$`AZJo*sjo#jM(If9M5lSiO3a+X4ZV`WX~0S@ z*5FcYK#rIISYT%Oo5F{Fxd^--e zdzTy|-wq`Nl#X{TZT&NV|C_um_*r_`2Gr?#JZ9P zW5|(av$mT~!$`B%l~{ia$z*cVZnx*zF)PH1Hn1n_zv=*Aj3*244EEat+8P4?wk&)L zw*S(2?cwVmKZFbBMNI#(@2KrKb9CEKw93#f^`^tTfy|a!v56sH&q&zATIq9}ukE|u zS}qKxy#;mKE$)pqLfECSWp-l}Q0F844%otc9ns@B#su3f*qi359&)V_IYMz3%s!Q1 z_BpO@T|^`u2|rJ8;vOp=;}EwAOV6^SF($W?U-75$2b@Hk!Srb&O_0sQbiJ-IT+E+Fgp#76mtE7^z{)s&Q_sHxvJ;r&X$ney_31D(0 z3~(ws8hBAiva?wVLhhTJGm*Nr43f&DT`q^eR*yj>ypsmekFQZacs9KRJ;O{CB_Rswo#t})eVRd0DxR&HB$O;d|5>o-jAr2)9nFWr zb$azw(F-zrN<|?Bh64?562lzx)3Zq!zS2{hzXa)UoNw^QYx!SO) z2>!+&!#K#Ujrc^3V97~o(jC8dhEIiArScT++9n;gwa%I_eI$wLL%yDG@a?LV!Ll}P zEB_>md(KEEM*2O>dU3z=zv-v{3HeOELDe$MWm56t6+%DEWo4#Sx?VBB-8O|DQjn>c zX=rMm6HFFuk{F{c^~YR*9+!jgLE4r1rZsTau)A=qB*2*?f1|bIEycV2UbQ>n?=^Hj znFn8lyCT?IcH7&-++wUCYT9JSz5^2x3oi#!DLy3W>|S8gh-8xUUz*CHz^?1mLsNW? z@k@z;)sOUWyhkAq>z1RgyZg_DvR!lyKAPC}Od{mqD+4Ya(>-cBUjKAQ5pb)1kNYcU z6#BNW+QQlA@2vqRW^SRc;3;k#JkHx29J{QxeV0jzPlG0%L*|yv9uRr$M9C>;aXqr3?%C|97F{XsW-r_ZV0Pk5sA>T0Ip(@m(A58ersqS!^4OzjzW+S?1{i~|64R}el`pGUOJro3aht>U(-UH|$*I&86cV9EK! z)fjDbE6cUM`wSXDAsDZUbpS7?-IU^cc(OB%yrvlCv(N^EpT7d+T#x_E?TWtPN!7Et zUlnrY&EyQq2YJJ-c(GZ%G~|S3pXzw@yUl^}nPQ?cKzGG?tVa#jAf1d zbd=fXnVmHHMDm$a#d5<6TYi|25Y~}*p^ zZt}Z&IIR~SJ%%+Ido&|d8g<`Z67vnTR_?PV^i5EdGRU??U8MTB`udH9T5$ShPA*Wv-zt+=i84N zMVe@EurweOpM5J;Rx&>A%&iR@q>49#ZBOK0HbGoi18FNPfy=hn_E1|sv@CvqUPkG= z#Bp$)WcBgyk(>|*9gcDvVz=~yiZG@{=R2%Qt34Yo#mbGR-E;ouN;AX{k?q^ zD?WOwy9MDtT^hJ>gDX(|)3xoQ&Evhw$6VwfiJxlgPQbO!Li)22W3|0({{%Yp$uq7NJoFDaOq$yhVAS9GRV1yx@MD8qH~xFH(wT zUYaPXyptZtaI!Vdg6wGZNNRfeI9Jp8Z)`o%Snv&K`g|J}yYdUey+6QVR6c)SJMHF; zJlU`3^`-JdpW2~~p?6RIS+q8O{RNA(yP6jYfT6{UXF7Pl|1aQX9x7-=;&cDKh;gMc zw~w#FZ+v(hCKkcgoo4&@fy+0!nuqg21m$PJT8*u&EC-%ey+PnJ?Z>H6GFvGB8mL}_ zWIXa$@h-o&#=^6Q)r7du#|Cul2Sa^3cNwnp zO}8l@N0`?*L|*ypy06=6Zh1yr{L=Y+k-RZ>j%0rtDh_&S2$5Q)5K|xgYYigpe)5MF zIOl+U&Y2ido`In5qBB9<(sKCjErn5FzF9Mqhm-42S29s? zPHNpj543p`6+oo+z96Q1FU)S+32QSIfpi4xsd~d>y zYu#)Gs<`ALiCBeszgK#bJpY6sf5P77wf*?jy!x<`G!;VdXx;qBn#IiF<)o!hpl&}- zvwctbi`wc$1*c}beKYjPq8+lLv$K{>T=8bjEPMF1z$ z2+q17#8?3BGyR-ALA(sTlwOHIGUSGA~mk;Bzs>%o`T(FeMwe1irS^>yb@i zZ|9Td?P!i(C0*_gAu64kwZWlaF}|h6K`t)Dn1>+afMK0pMC~iZ<2mDv=jEZ6CS#)5 zm3@JYf#6R+rw@GePa`fSOHj25({fJpuIuM;lUns`n)PX!2nw34Regw;yW^2?{*RyC zq>JZpYU=I5b)ijHR+^HzG+-8^NGXc+h?JOHh3v6~ZWfmf)0sht!5hB?Yz9@`(Ou;j+?Q;#5BIeu#t}1~!X&!69iWOnM4T7(e_s^# z&B;0&TVwTjJxU#5V64WRua7@2s`lvNieQ&orb-&W^^lVk>;_Z7-JCK7Mj@MW2fX%Q zFSc8j&PHLz6cpR8I7@Or2cyONGI5@YXC?seIV^6T{Vx^oF;l0=@YCCrgN)LZnGL>< z)|^O+xkKsaF01-u1O9D8g#$1Bb=3R@aSvx3XZ&JtCipaurae19u5nTEF}iAEMpjuE z2?&Id)C@XbP!q1x&ZD(4&IGupgpoNc21TiVJwXr?gdev}q2XOAgCxV#N>~ARm6PGR z(HR?MLSQqtcK4O<=%uHZ;??QVQ43rt%VlTii7tBzyv1w=Y?|8Y>46`TqsJz#+g~Z9 zyA-zTwy2Fxwpw$&?Q7o(`QSuq>Gb0mg&!QT>n$wEv@5nS6lS=G9s_ujX>&g?XS@32 z+Drz8#gPj0ARAgv^vP>q13d4bZEK17AgNm&O0F^IWNom8hzt%$q&+5EZ!79oBsWUq zW>}1xfA`i(FW0C&g$RIRr*XAR4g&RFYVxh_@yQ}otqGDTbaMs#C7^0f|11{{RjZ|c zgRlaEh{a=2+|0U`w__^UMS46oL#RLg=mha}hXCy^#Jols%xy;}KC4~thZtOzcu^}W zzocjXhyEGey2@>Y;jw@l|9rdNe3b4KWYb45|IFzJu0kn(9+dZqVh!?S3h`!@e_dpo znz92nBTDXyrVy_rkO+#4?f&XT62+8_+j5*pMkk^|Y1(k#+*v!t>dm=VdD6s{MSaMb zmvFLkxP4bp8^2V3#+~ar>TiDetNj=kH{pI`-Mqj-fj1Ooa8BFl<)Sf1Td`YfYaP;+ z)gld~bSwy-PotZj1!vcdh!0N;PlA8(hCWP$f`%Ni6TlDZEw-+w%Rew9JPTNlYV=?{ z?td#k)zpfY7I@UEDk{BvGeCZ4d{K31W-CHyd}cdw_F6#W^RU#N00(g=SYCBhf7z{) z{u30frOD{u(7^QMUv@ILl)j}i+!D72o*ir0A3_V)^}jb`Ac9MD&*LEF#k3b`qrFlI z$PI5yEGpIDIVf-cEKYZzXK(U>8Vqs4TmM69`doEhzXr zRwNih9mmPQ&TDNHKd5)AVbCH+)L`J;G_}SCRPhhrPeekpUsO*fPEP;%#BR-LRk15t zFgetgy2Jkj=@7E1Dp$ME=!B>P`%(HBmFT0#R(XS~Hn1W|#=eRl z92(i^HHRGki?-C9r1e9~uXxp@1a&D-^`|Wc*WGGS^cv8fGTd7fB~$1tI1~Wzq2#_I z--`JMlNmQv#s<2AnUPWs!u5Dy)|^7ni57~OX9idFJ_TflAjY>ljRol)=FJ?*rj0HE z8P(8&onl-Vi%IUP$}L^Bp%0!&Qs_jxtcbrl8et71$N|o>1h^OT9aq>kgDd9mZ-!d@ zkxAJI7Gc<*JJht5aUZ~W+0BeV_8Ye`RnPxyIT0tW#Nr;w{Qp79e4g|wn(NBnkWWjd zm#?9u`s$~pXYHaQcUjFI{dq;_U&9mW)ODYf#RprfaoF&->73#E-ptUYEZMPTe2^9! zHfXyFYP;w80Znx@GjAFvnPOaYUNi+6xL^Qu1QkFOG5KJIsq)LmS)V`mK3z9~ZRZwY z4USY3|2l^UYfZ2%gavGb*HNFtnaMJd(Qx)c>}Px;Rs0aoPA5x?x$TZ@g6&SBZx>Vo z@lM_;v~?($9ci)Nkb*2jxl&v+i1y<+1UVYTX*z-!R(9ki=S#MGqL_o9$gHTaK@)_& zv^GV02G(?+!oM!(;{~Mcl71mJ-q$gprBXVevz>rY^wP^fz^~Z|67BqEF0fYgrg!PU z8j9Iu3kT$<@Ql?IFS*k=T%EIZAb}!%PblMVz!71p$0ui<6I4LU zUIr7gaJhXsTsxJOogFksu0wQT;ZWH4^P51G0L|9hXV!npcwFmK&ct)ry*ae2_cZg1 z&!D1-Ge4ny^eC;pL%2fRI0QmLuH118CC*K!?lP&XwZBvSeUC~HGR*{gK9^|U=^d>5 zJM`tJ5x!5`yH9=G_a(OYM{bAq5?gb8G&3(snpv)1Ah5U8+Cp5aq=zU5Z@qq)9z#{_ zo`_c-+Q0*aRT%Qn>d`dR?mTJo@^;mSy8lb85bk!?(arptKR%@J+l0V`mlrl8c3GC_ zP@8sfMylU35g-_s+Q&^NDy%NWI65>Igl?!O2;^TVr-lVDjp@T^x`{I26ts4labmQ9;`I%MftB$+3hd?Q3%~T#YlG4 zuF>N<#b`f$WEGEt#2=&2Ucv>dEIaXk>WU%7*ls&_5@p+nL%Q9u36;#{gYmzkqkPSc ztkaW)G49&MwiNp7u`i-=meZ~SINFZ+--MQh*TrT#4`@Tr0qqyY6wWqQ=gwLftaZS4 z`k*Ydk9E`5=s6hDRsz;LMf0$Ppg|Jd1(3oNLh(fg6UKpjmy*gYWTjMo_B_wE$i$~V zu31AV06;Hn{$TG=ZfYBGP1ujhOar7dfz1O6l>#hz48-UD`*Z{xsCK0&CD~~?*y#-r zuAX+454|mUW(?^~!PV*|2!3toQ z579m2lcJbJ6BA_3tGS{{_pGA4_QySabtv&?<%#xPXcm*V5_c1g=-2cf04Mv>Ir5Sm z>h-Uz>r48(nPcVsU`aRcPTTgJm8V72}Zqtp>Ns;_iNlM6z<+lAd z64!TwW(?k}<3#h(!GmMvQn~dLj^-AGpxZ-`IlO1o@K?{$M>QDWm1vpq&SA*O6U~1+ zV@YkE_)MO~7)3SD(&90B>0RHCVeeza&=TD!BG(|GRRBh(EhI#(C9i) zKB`Db1$oq1L!v`HD?d*! za_$No;j*~0a^qLWm3Ja3$VF?%i>Z3;uY3~*oT&>kZjoVnM==3NIs&Zz=*{dn0mJlr zspg{GH-Ze(XpN`y$Sx!){5NlopJl0UmpA?*!$?I)uhrQVAHj6qXX19oj0L#{E*DE! z2er^ca@h^=hC-X3=H~c#yztQA1u2fB$lA9jbpoH_g6WU@cEiwLMAPVoR%Me8TIbPU z^v1s*QQ*~vo}O9s+2&&OsQe?SWE6&40+OVLzCchba^v=!1*i{x>(Vx;Jzx^Y6sM+Y z=)Ee;>#BuB3%n4G-2(h*r++QBUOmJ{`EA{TmJ~?61^LBE`{+~EK2YZ;`cV3ZWFQ+i z%5XAzy!so)W$Gnj8HT>>``=VxNf zTC>lvvE@tl@Z^)Hbsz3+nv>iZsVAbY`wHgA25V7IgsXadx%BSXf4J|*RJ*d<-!jtZS_MKU$VKRRoCf3j99kOwBTEC#;33cl%CM+iQj{(haA5aDk&_MP%b;Dm$-a5 zgHUQPL8eF3SIehLaF^DG8}#yb><_OlV1C~c!IJK5TQ7+{JGel{QIszV^0NdDpwow! zHUWMMd_-Wmp|FSpT3+ZykzyS~xBdwR1{o>(vN4SshD&oo2Jhi5v+pQ3endm^fJMcad!B<0M3`UOYssod39>WL8$@#&+%k%w z(}fa1?*uD1QZk_n%yD7Q#Lkx`pUpzZ!C%A2j72S!$YH~Am7!TD=U2>rA`bjG!_lrK zFL#rM0&Vk~`N#e&&Y6WB@$Z_^gBaMQt1NxKDg~FG*SF8?g*-W;8R6>d4khL;y~95q ze*ZyJBu7vDcJVA79+`?T;Y{~o#urKN>q}ovQOrz$S=tqw@%-ld9-uksdPqwV$z~tH zKIFrv?rBDH_&|~6gBDA28Y)uS?D3!4@wk$LD zK~ib4Q?g5HMpCxyhLEu}*57;1>%PCg?{QuC_rCwRj^jLz>o`s)@6Y@FTAt6xGjzvV zzx0nfQ%B9rp(i&hz^8rH##DDCh#umgbFX=1sb(fw;a1oCiA0ycthhzslIsW}vqay( zu~;;(A8F|nKnPiVk3xHQxH`acYsMP(Upf=91sM5}MelwTAR?xxIF+*s7737lYk`}C zZY1Z{W+Q0g9|pkASGy0uG9kBw%c9oaTzGru=VQS#!ThA;bx-(F!qson0h~{ae@rb(iM^ok7iH!GJ_07o30bT0n6qKvIUr*3_ z)D)h-tZ2C7o0gXDJGzxVon8IB!EiP3Wp_-kHVf~C?B%~RGfE1r)hmr*?nN)$AjBI0 zAtlg;`qry#4mHt0p20;}tS)3mwhz%fzgfV0hpUwGc$wc89@cM41`orBhjCii>O0vW zg98xagc166Kg4uMbX9hdOV{YHpDaUMb(nPrH4aLE+yUo5OyuR=8Jz8_?(y-mmQ)2u zK8=sf&Y7M>)xBkZ{kvJlbn4?6bGoVG5sjw`$K|)oi%=0{u!u`R)Ydy2w1;o`pID~q zg|pBBI24j6nUU1)DGcmHEy_W~+6O&Mb#Z80y9F2l;1+tCFc4#n>FIu(uXB%Mgc0PV zGqkSTW}IaGvt&*Ws_IF4s%Ydz4Nu4TjtD5Qil&MdiJv%Bf&!ElFIjowdovm?{+_W+ z4wL8xj!k#1i=>#DGkw_T;lnhxr_u*Zih)l^>6m;8XOf^q?DEX$%S{2PTzz3{{gFv?EptNUHs@?bvumw{p(ts`iD_t} z25a*1?)Ed&l4k*uX@_9YfMW&S0+Q}XSVoaftUG}Nn))Q)+vr%Yo-k_+>1Cz70xGzy z$LiDm{b(JomkpoIG{e(&%v)$<3Ph>vq4qNeW_EkSw2SVrT#pHmXqLJ}^f#07_{os< zG6)J>_Y?v)A8D&rW7kWy=DUn^bTQKh&%6VY_;%*DNb#{UbYU#gl(m3^qBS8`a$BW{ zlxliThHM^NS<@WgG&B3Q697{4TES;QOp9#)F;XeIfV0t;skP%H-*vOID8v+4RT;|l zhcl@!as_66oB?riJ!@C!CLjA7f%Me*E zs(G3ugs_yajPfIJY~`<(RV@1P&OUsio5D(5@^MFxKH@aib&!M!GFTZ_SsaBX@JMBP zQ9gF-`;!wZsu7=04WXmuu{_Zc^LX<@$XIQi1Z_8E=~QUncvF!dOGESe-P33ZYUuef z1yS$B$;qcJ{w=S!o|)cMy}vJFT3iK5<9;B2o&z{O^kCVBPh|>Vslkc|kji^{`M(G5 zpT5@6T!VdDaks~ct@{To^Jm`99;xG0lAg`p!sM*_{!x88p=ZVp?n-~LJeI#lF<6{T zUwtP8tZERNtlu~46V*$({?QyT0|qPjM!x`CYTUZu{Ka3RJp*@q;ISi%So&J0(CaKy zWnKHaL6x5%(!f>6lUce*RU!6`bomr79A(zCz&(t3fdR8JgPSt)D{h4ZmbaMlY2e0o zSwm(0y!R?xaKY@Y6?jH!;^YQ8b|O>td|lH4IKwfcEjAg!Lh0YK(4jK7Uw9+1fVrsi z!=LdwR8Sm%?9#4uGWedZE%0wz%QSY9VqPBUsD$6o3;|2(|0Xm0PvxW_Vsa_awH^K1 z2LqQRzT3@g-uuSXiqBZO-bQ)zr&i4ji3kHN?)LGC3%((!WQ3*C55?V?;w<-c7kSRo zVvtndqeQ7VI=C`eoTU`x=m^Ol#Z?A+C9PC`Xgjvp>Yp3ZhPQGpLWz4foQL1p`~bKY z7e=sR$I#gJbfkXoFc-f(=yhM`n?a*t(crfEd8d9RvoSE5CT9$1M!(&jI=K=b2=bDS zXzbNWd96e#W3Fmw1%ALUVa#<-&X+~uNnEJ%qxM1q7Y+H}K^`>tJTjTiu;7xHEi-(e z!nAk0v~z!9lW!6IifMdpndv|b-aUxM&yx{*O#R1auRr zR#}Pw-hL7UqO+cs#iyCGvfxmkuhe{=*%d+8TcS2YMft+NZ|wb9Qi%xV+pKJ?{?@qP zV|r^~lkZQ$g@#bJO{qlOX8J71*U8=+waLB8i|6=Y<3}^B&zc<T>tvK@`m78R(hNhWq7GA=20@9Og&Z_oJ@p;M`c0R*K{%I2T^Nxb?Aiu8#^jT88hB5y1Grt$+XRTL6+vb>)Ab zX8t-S3`nFX4MiQW3zgbkf1zrM_@!y`z0TDzJiz;!<6oyt$Aq(1#MW660AmL^)1XS1 zB&Ivd0=B6BBIZ*{FK%4JH>`)NS9?^n{>Qz9#nieV?kla8f#7H4L%fXu0>zYcseFi_ z&6PWEOkVfO-c}p(t$TM^tLfv+f+~tsfoB87%FR2C1~~_h?EZNYgZ-)7McS1l-jwD% zSExB1;Q+~p2md+2jI_~@g^u(dK`EZ)b_HtfuI%N6cs|58je}(Yk0b)^tg&=K_Twb1 zp?L5;-|}BfK2W;-=w(eD2)U+SMX76>=o+t}{rM2OG;=a9T{=E?@Jrq`L)V8aF$-vs z!=2EpI`@FIx}_7^E%)@&OXSDL(MylVyP!jP%#J`rRwN2+op0Ifyx+WS6_`sw6h@Qc zC?2dAwURA#{L7J4WeUTc(pXcKN8oYAeH8Vmb4t$uR%n8DsWVKJ-OYFH$J zEj(<$zkH{4jYzCHo%Ulf;P@||6mn9+FZILRJ{1ReFM$|`Y!G4bcQ>lSpq3|}*7#nC zs8>_VZ=)(Be@qCFC2wVdm`R(rn7YZGJK3fmXG0YImfaUXzE1(6DbQ;5kI-3nCr~h% zK?`J(()EynGS^cF9>N~;{zz?2n)!*C#TKPp;L7H4TaoU7fr~|!5t0r<8e_2Xr7J{! zr+4}$25<+!`sbU~1yHA~|6!V1&#XtKTGv5+J>H<~FLX=9jn>X~>nCGLJUQ4AkDPp=g z&GYkD%NX=euUU6nk@{-0H+b|5R}t-m<*9#0zlqqG6ggbU8>d5Mkm7fPzYg?XJYG49 z^}wIY<_Yuby~&vBdskB(A$diIMpFT(W%TgN>5$%&^**Q`()+KWOE&&L9iE*d5#E+} zLOH;^Q?Lybk>uV4V88)`f>fzI_`BOnH=k4ntw=OF!e0gSm**8(nDf~%InRHN5fZbf zj;nn#U1{a|q^GkHFSs~`gUWzl5&mOoQz&!O1BKBt{B3wVAqu#pEJ&Quq)IbbqGAF6 z&TNAWQA@_oG^73qeT^sucy;JnffZK611~PYnN<(UWgm8#^uK1;s^j2kL8kW2&_A;M{w9U&1j(JldgA#EbSyBY5`_gYUze{%jUK(d$*J>JC6x$HIX-^m+Wire+xTe)Y5)yLL^c0C&(1i zEs+&VT-BEt;!jwAA|W9_9Ip(Rq(-EkEB1}SSXj?fgls!#whH4!%-&Dw{s?&iHW&a)5b5GWN3{f9rW-Rdi?i(KAP*-rtea4 z$GMEKr9ucwnTMkAewL?l3ZFOgIu7ibo+}4Ih%pg$OP@YgVOX^0&0A5wB745~9f;}h z0O?+U8wh(4^Y^P+5y~thx-|77PWB13a!9&I=6xl$sN&h9ba;3*hKwx{o#mX60}e%o z7lE(nmG&q~t`~1D9a#GiD}PUlC7JDdRB%7BNZHsnw|vXB&-BZ}pJ{?-ek(=7Dkk-MPx(fQhca`V$L2!1pPC8efS%^%mzrE~2 zWo7te|2MXSVVY9NQv5Gdcw8HbU0bDl(bv2H1IGGVBVUm~gjXk8bj(}k)?1q|=f||qJagHgOoD>?bs=moW=5y&LtV)oM8HC#E8m~ zw2!fg>`F_sLxTUYQRxy&Wm3?L3nA0dGP2#I7i#;o-B?y7kO8n80b3D#e`Z=>+HNms zDA`J~@&(00U0Z0S|0MCJCojUYTomSv+0R44llM4E#~FWeUgo@)VAqdG1F07%k6*#1 z?N`AZKmL0J>u(c^9MPxJvx^jwW<8Y#dH`oynG8YjP|iV3zOQaGBB0Pu_k*nNs4~pT zfIAIPW$*Fk0&UplU9=OoROOog%HdFVb~3CMReOG%l~-wdGciXbScCTDNgtT{f2r+FTpD() zYj}Im)Vd{_Pc+GlKk~R}kC|yd|G2OHDBSz@Ci|b`8B*pfn9$*3qHbyJVJtZ7;4u#) zP+&Q*0=HTeSUQz;k|2a7jr-ck)#+G}@xe*@6hT0;md zxs!}Yc-W(IWk0UmJtGZ~WGkjdCzHZ$$@~ zrqa)uq;k5tgaej6ix-FQReWR%wbbu75|aDAKS?5h6NEP*b>e@1vvy6q{*-T{t5n9U zNW)ryo#ParRq)=3@AH9Fpc!=$ZVY8uEsZ)F4NWzPkKxa6 z^<+=I5LgT0gj$OjXK2ToJ!cPTLOtBuW4qVKJAA7~q;cDEY@bU1J6-s?d#}NjCCn;R zhsOe{qwsCz0Oqkn;9OOa{B55k8js=L)fV3l2_w~HSdOsH+C9%ddutoI{k{mv-3^Z# z>u|i4DDAG;{n@|SvJ1B14K@$&e@?Q5-_2wAXmAWo`zfAo5(u~eF{B_VVI=rNU~l|Y zI0)yfKCtQht|^)n+8q2KZZXQB?IfZ5D8fC5q?jJvNiRKQzsjV0-PI<)c!vWVYZ zKn5>t1KK=$O_TX<5D{t#2fC+p@NZyT13q;Mc@g|Tmi;Q6RWdnzW0B_)-H~7Z`}3HH zi47oT8pteZK%hfvqTdPByiH#8)gQ@6Ba&bi#zz!-LvlmI#&i)^CO~NZmMk~bgFgL=J3JG!8s)zAG#(LDUgTC(`Vza6~u+M|7zJC58ap`^^lpX`3 z_xk3T<`va#_9KJ-mXUlmNw!JW(U==S+7DES@V&1;G`FZI%xdmoHSuCRy4i9P-lZDB z&8SjX;k;Q0W5Hhx4)D~PRP zDL)T?+X@OKnQTP|cx1n1KX+RkACSjJO6LG#-raa8v5vLh2tq`=)<5zRyke4$$d7C+ zZNuL*WbyLJm&w`61bvdg%Yd@jbnmK9FFbL8(!`%>7Sw?32qj}cD~XH7hG>jOOLK3? zt$rGNox9n%F+Kuq_&()wcvEKC)#UFAVfJn^0bk$Zi@v>oQH^s{MHkb@zP6g$Cv##* z!4jZT)y;yV$BrBxy+f~OZ&r@~HJr5MY32Gf-sjV6|J?h}lGLpfsM1uYpmf!V>7c~; z?e|xQ8;k`JMC1hZwS*Aejlod@dg;0mxs|D)+Sm!|)>$4ANw62CjEoI8J-z>dv-e|0 z4u2a;^m0zJbBE-Wks0>6!g zh>xPa4wy4f;MNQIYg0?|eWK7)J-~no2JyG)ty@B+9kDSfUCJn(dnUSNAx9T(WC6L8 zAmZC@u1z27OC%x}+#4+Jcxc|6%Mj-Y&KjCrDk^>K$R9LM^YLF##R+1+YMBYkcIq6*3(}W`(uL`;fj0Fk`iiVsWH$WMb zU^(&r7gFmRA0Wh(!AkU%@C9b%iWLGZtvlevch0#Tt7j16!Mah00c#5PfYb9I-i@2* zvZ2gEj60sG?pK)G6CSmC#1KF-x|~(RbHLueB7PY;GQoN6mw&YENpomtDdkAkw;Wk2 z(u`U?%xt93S5g17o8+V^e{%eCI#*KVT2wc8bXpeeg`@qrdYXuhIf#f^yI8M`78Fcx z{NQ#-?x%SdRMC`P1Xhrd*T}0`>FDmiRpzc^0U6VHk@eIm)D?Zr3DBVMAr64cCJ$_E zWku<3$Kw!Vf)1B~)E)7jgV8{J!7K?P^v}I{?R{pjU4?IjH3e)#R*VMcE^+(zJos{& z2os12&$=>cA)6TNK97TbIrkYaY#I2&Jv?54z<&`2c45rP7CA>w#{j|$Snar{BwJwa z=6+sXew?HJX?8i_SLjS*-ZGC;=-RHw@?EK%zn`KpE#bqHeD`$nmZ{2rP7L0PnZ41I zDy**B+~Di=`j>%O2`o!vcUrE86s6$%~<0^pLLG+!dWOs_=C@Dx0)2{TVzi11mn zJg@g>@=Blp1EU5;CKob&0eKR@1}Gv&xKUC>@?}Ic<^iT|+!6^tIZqw6{Eqj}g%KpP zzC5?CVWG(>pWpGIehj`KY#>(v+%A`|`VI+O@?F&eKiRc5R9-X~XM)_iR780_;3lzT z+z9~>oBbtiQn;P8T~Ty-O}sa$4c|2;i~y>GQ%~wdK({}>N0|Uf+L(K)d^Q`JoST7` z@JHJ@>+g=P^eYjoFt%WN20agYWhWM^1<@p@Q;BUT0M7%N0VmYBxQ90rc*9fxnt&Ui z6EaWFfS9w(oNNudh=Tx&3JOYL1f}KOwfr`Uyu!IS~`alV`ouJF@JDl5XX5eJT7;=F%(_-hXBSYpenrDVhm#)U8)OicrWQ6{c&;xt; zf$~2K-InDw5&N`G^(?*nrxKR!VnOJqn^%!Q#z|u4z$t=$45+`fjKTQMu5Nfed76R( zAw+-#Fy=w(@~u5Uz|ITUm>UA~Hd$mHL?T{XLz!l115RjCn}7}Xc?3Kd5Tg?|S$&ih z1L#G^hs(YWwWua2N%fHW2bTm8EXS9*6gR&@rH|&`D5ii3%2Sc2pviPp4E9t`@bJ2B zL^g`>n?MWFL2vsZ8Nq9-l$`pj!P)n^IM#YuTf*=VRC3d$PQ>4rw)c7SehB<9xVh)y zmYzluw>feSeKycDm7kyg&STwYH*GQVc!p<8+pv4NIqcU$%NXmIxkmMz7rSCKSp33Y zwTo)+>D#P->mP-^N*>+1aOhVxkL%i8`@Zw6*moxy6-M|8@MJPzC7xxL0RTz*d-aV(A-m8 zN_Rh5fLc$mq>*NRs3dj3@m9tGUK>G#1H7yb_-F;qI}2BP)NX2@oK8fd-eSr8As z|0gw_6WpI%+RCl(T!nQ}M>Z)PisF(fM|k?)^D%!q+dD%6E7W%hSTC@LESex_@R|JHu48L+vSRk)dx zC6x~&@N%|Qj{r90$1~vaoq5T>9_6`Hy`JP$W;mUmCU2L-JMd!v-g)W0~jfH2s&YfX=wz3c`rrhe#<%LN1OhBX&@ zYOAeCs+D_f(LEsf*SDXbdR@|DHi3hjBYPV4J3t07CLWBd6^Cr27)|4$g!dp&@A#yW z-GLvj04yRp+2_2a5tonngc~ZB;lVn`njT*U2g}3VBwrf!u)Y+NzndNW{diZ9fmhh{N z<7_#HHac#Zf<;@OqXsFo@+t(CCYN)`{qsJTyXwK?CLcwb)%9xcY^I~-`NWIA_O`2r z<4+sIqnUP(w~Z<8Jf^m5)%8!``KVR2yOr=)J9_M6{b${G^a0Wl59P<0D&U|(h#_rM z<~^g7gYr@k{uQK9WtZw&IF3|1reR$q@N3ZeTlR0JgL~ZwGRo+vXznB?7Fi3%MMumKh<5Vf-PH=%W- zm!p>K!%IK3HxGYHl{xc2?>wJle(ImYs_>|t$XD5EiZq$a%*Y6938EG!I$&+2{e$cI zWKsZg{E#9S-Dun>a;i)A!TKniY2d=y+4J-wN?oQ|Kc1sB!Qf*dBaZFG_KA`tW6W9S z@evkdavczEL>QJmTW}V>bdo3WiR+8%t$GFKx3wIlN7>r^^GbZ0d{Pi`*qE=t(P_HW z)X2~rpZ@cguih8B8pkMgKXs_&1%C46Ur%)tJSg=fdJ8Qo5R>MD?xD~;N7WN}gou}! z0Xjfly`pt4#>(E`T6zPBvT~KyN3Z!EhEv-b_(a26S zrjnTKMtxNrwE#P3{D2c#8a!3o6HX6F(rW+f z3po0RI>P4HQ_YRYFLv{O%1)z#rw1cwR7V7y?G4rzAOxgyFBVq+uquhek|8)2PD5&$ z>Yu*|Uq#>7q4J+B9lNjM0J_-DRCoP@8Ekh};_F0NI>H=;gxeDiT!njHeiGYvfXEG( z0CM$bVkD_Vx?6gEApuRu1Z5a}`YTAl`M)H~0lrrOmSs-M6g1wh!b;hvTF*(uk}@*x z#eM*5A*2!mZ>IXmvalqU4K0T}7MBFalFz&z!>2eagMDSrdbC?jQ!tOOePl z=EqKFg}*Z$FKrC;NH`)n!RcGCFd=94QOB*nOis*`2uF96*Na67j7Ez{<=@bnUDrb= zIt9eoVK09*XnXu(zBetv-qYZbc;16QeF!Jmn^sf{5I+^da#JF_jCGJ_ih~u1b@fBv z9^f$45n5TaEO!*%%DqV#p@p!714cgx%Qn`hBN4G+WeQ?~phVzej`JfQ?uPo^b%Oxh zsqbLBn&`Kz!9UI#^wzQuKvApKea=pw@|bwVw7?%}vRm1b)Tm{M%PICX-Of;rvHkgDD@n6bQ{Veo zHy>@Ek?@85(rG!HLWDj#F*`8BgAjKp66h9nPWN*$bH4x!-GfiXH|rMj^^Tn^Dooy6 zSYtOInLE;qAY&4mFI44-4tiMK72D{z!xX+igWHLU?ump4?9UVcdcX7`7#XBY^5_ui zhc#(sMj%{8b@|Ey$eiMFhJykVGdF=Z2BjF7E?(X!h*v}k3#}Z0CBvdmzkOg%riEK% ziPy^^P-}Q#i_iQne$^EIjivjzM}x49vi$wwz}eHy4hr*frg{ciT>(>2_1_R0=Z>_~ zex^$^UmuXdkSRvrc+FC-R0=V+kYN^@kt6>52>SmAIR1;@z@IC&a+LQ1 z#cq`Q}SBvntV>Ry5Qch_?TF z-F1hqxo?8n$BPKef#yZw6Cx(g6bpbLP)s>1{$T}z0V+AZ zo@$J0v82#ATgsLKM2u4w11~`c`WaZmkerZzFr?s;frC!aI+T$Stwd!Fks?|h@VBF@ z+Gc3~^BHg|%F}_!nXLY+MwsQD!Dz~bEa@~8J{#u=Tn!BeN>K~w=~EMoFaV-tY6IF9 z2R+>!FJ!H}xpkT9#+Te$mSSNSxZ;9{q z70=}BIg~Eu;0+DYAzfXOW~a(wB&Xv{0e&>Z-Vu$ALTC zt95eBe2&+NgPUSkwM|;Vzzr8+i;@9K9Wc7trFEIWbwhNEDRDEA(z#4~(gm1q7A~jo zEc9y%&HR)Ib5Se8@DN0wDp*)Jp$18PnKR%Cgo~efGM|*LgC#m^Y6A9w&W$zH??95V zfV-eO#*5l#HJG*RurgHxB`jSUrim76Z(p-iJ&@PV9&qeowRL|lW6 zYGn^R>LmTiec07aD*X6PpCl%buEcArg%IJr(D7&|3BU%pRdlCyPkPsrX+1Mw*;p!1 z!+~_4XG;OI-B1BK5b6NZJYfIfZkU_3cmjAvkDtRVv&O-^KP{TSuzm^j26K)3O8LBe zZA%!_u#H99m8&R8V5tk?jper%Mu2sF8|9fJ2oil~tloM@Y6Prs0N&0hBZ}sRf1*I>99F|8 zBhEW7ZFzKoFQPr|LRP3YnIAxXdChXXO!yE{!OWw6n`7d%6;`~E?dA6MwWV{1mJ!30 zs+=Xy?GrV97bb$??D`|Ct&JJ%`r+Qsh|lA+Ojj#T{oPCUKQ_(M9iQ%J5k-rR_uv+t z_I_y@WtQcIla9artyFj=N=|f$x~ZTxv(T=!xgY!Hz8T3k9NRpTO&okt`$qr?hHXV< zkUSl_;7c0VLxO-0efJe0d$_OKpDcbz$M37TgU)z-;L#yYkCoQypS2U5u5fqic`wZ= zQ}r~ug>Z4O!2p|v{X#kR;F75sgW<}oMErRM#0vX1&X|rn+Fn$lnKv&UvBjNu(Q zw~JeQc3luq*JZ#f1Ah5&5&YzUWQ2eSB2W|5lDh2r^LKJ)1A>px?y|^T=_0)b-{X7$ zFj25L-zZPFOqM6UCV0?U36W7;W3ki!XJbDI$zYj$mE+P1k9ZA}>V|T0 z*ojPpxlUUr2~Jl9l}?IvW=1qrhN$LvsDb2I62X#&;hKG7K%O2>(|HZyB3@trHahTW zFw7YDcGkk3Krj~}znJ(5oECQqKX#q%n!jIeK zpU&%F7n>41D3Q@gdhecZ8|R<9q$!b;q=2m@t2Ff?V*nK73;+{99xgdxX3_bEL~zzy4{Y{86&P^MG)uL_sk1cB z!(F7MQZTl1Oh)8<2TWfmLZ6{R0dy9atSp4UR4mX%#zh?rAYsqMd-p(+5hWjd9h_*M z1}y@J;5evXkRC_?yn7oY7?}eV%JsV8e>wRfo8@I$)nr@?5MbQ}MSqkB)apR=16mPE zwoAr|NXHxl)LxL5wT(yPNHqRqO7Hh4&3InYyUak}C^M zV26CPXG>=uBrYF^P2i9SVLk+4rn|zCAhwL3dD;lP+p3!d_l$LP(Ldr~K)Wz~Au!4M zgwxJfOV>-Dnl@mw0{u2YJ56P=lZU_41dg!T>(r91wyBNI>M&HM2+Ci$N8AQ zrI@du$*;I^N%vDIG1T>hECE}ZFJw`${ysGcZ@eT4g7%j(iMmrzEpn8RCBFFmlxMZt9pO*o~;Hu z!GEc+fJBs0{`|LK(PZ^E7|~VQffd!KOMzK(hiZ2-+j#0G4bJfWqdNgig-3jd2!_c{ zDaktf6BhOQ6WLez^b94SM|q^d{Sg?(4MTC^A(le));WNpu&{T1Bu|Z=87qS zYiWI!Ud|606^k10DV1PQpexl4S#NyH8v=v)VoRDzC%$9_> z_SIGjv1z;45e%@5IE}wbpOL@b5!nqgU9n!Ka4KDqK*q{2D1$P1tNXTOnwAjTbT^1@ znNSUUyE+>1J>5d(d0O9;m<*#G@%ltM3TBEU_WWGn#sKjqj6~))q7Ne#iSOgzVhu%S zpZk&LOrXcib=U@@-$kQY%0E0S6K(TQRPa84HG?w`F+uIm?|xRR#6Zkd!SE&$IVIrN zCh!ytxuG|r@HekRi0>hIM7neUEZs<%StiMGfgEBXlbazahP3{4K$3Wn%}&J8j19Bz z=~=k!zpXfTtJqN2l;&N!OWnRYwi>pH7SXvxcmWrt_z^~5`%r9dnjJ%B7{G{wnFl>` zUY`UxHVG%Xn(aB23zH>`QNInJ1oyu9=qoO|Urh*0_1p8@Ruf^021iyELa>?wohqQo zC^6(z06D!YLg*hRwoyQ3AekFwIgvWaxa#>pirKtZMoGFNsVbA!RRtTLmb2}-B2u<- z9%M5Jq#}|`omngne08gz@6teiUy@#Mjk4pn0diY4D&24QK6dxBy<=Pmqi=<>aHhe? zUD2g}2rqikvZwB-Kqo&JYz53{rSmTPF3ejv;(+{vl?onNA)s{w8}9gi=go>7vs(Z z-zO%ZO`xoP)P7{C;@Sg2E)Y~}P~3)pY{*Fu587T@47=VqI`A9XO&U=E;7f3I{~t~` zKyfYpn+Iut>9v^JY3?4)lNU}MnEEh?Pz(E1z((_2_S=O@5jXsss#RWu8^IqfCwS|9 zSl*jUSl-P{vTj&Ee?sJ))M!Xgc822_90`cb@c+ zm>At{8sND=9Go%yxr@i4QlAwgSe}~8cB6x#LBPuJxkWQ&+n}zGSN?3|icM1tw0*yw z*htp+rJ+eZv<&#HNr;NS1u4%Iig$tp(;TB_#==JZSs;X&Fez)xMb{UpU=t8cA&XG0T(T|esVH8AKJd9!|HNUd_$^*g_>gj2o@P2Yr!$_Sr?$F8 z5KTaQB7cKZaK$cpwRIXf1%~7WSb6Zpxcxjyj6s6{f=W<8Ux-o6G4n8U94|TsV0WTF zIfs}ez#?w^b{CB^s{Jl0!Xo~*LXN6b57h5gJTy0|z8h`8UKm&}r9?NH8NiS|JsO~2 zj?t%zkAXSl%=elbo^~ey;ew<1^kRy&c;}G%0HyR-==5&x^6r}A;H(?RlBpg~*e3R# z-q3c|>h*5yU_1O0Ysa^qQTkgmcSD%z#NgdmR)!Ait?^e>6R+wOvx(B`J|xH;-}V0O zs(XAX#dP}nSLv}s9TDDjGRB&@q1~gs!6X|UHtSf>_~`}n+0^yqGWtLh9eY}t)I2as znw}Sn(Fe+Im&?|m*Er|n`urAo)QG||3bqBX@F~2?(c zN}OK2qL~*`GD+R0%+nk)IFE8bkygJw9W*V#DnR;vXLLuyX~b%_2sXKH#X}x2j@uoV!L*SO3N3VfdZP=#Q_Vwf7tA7uYWMgjpNN_@~2U?b6^5wbm zUTBv5D-oiiP`%SQr%>+EpIGbFtK#&>5p%M9)}Vx7G1hS&-09+grnI3P_s-Uj0o8)r zvDvPIV!ZXki0+Zaa3Hn?2!#i@!|2AshE+2wr{z`zFP~;9}ViVYVC*buZ&JflTcU(| zcb90>9_`1HU$NC2b~Y>Yyl(5Hwj+3Mc7l8}ZAJGXOgAP8@xiLU?@H-0kF!?l+HiS=yVa>m3oP%r2%J z$Y}R~N{;+)S-!V>v;J>3Va)4Ro4~;nARNl%v;ougpDDIUh9*aZep0mzV@^wCoP7P} z3uIK~jbDn6ti&{4e6vj0M&)Oj%jm1SIi=-2xw20CFoKtgeJf>Fenond2xR$2Nc}Es ziVdA$wOMYYTO5*kkYBz}8`2%vOhJP7H~6cyh1RQjF;;v!qA8l3j98q57E$ks&UCSu zn-}I|g&YlmVS#B@cS`$BH(-R7z6(SF6ZsVRuEA!lKmp4O$Ho>TR4hjsQ6>@Ql4 zEXUMbUqhv;-dn>jg+ReR-=<{2S!lNiJb6S5kX088?h6-&IYQ%>CCGTM#LV0+?mJjg zvCquRFK|Sz%-bfE6B(F~sd7+r0v-*oq25x`J-$;4k*=WeH6L@52@zNeD31nnqm>(gygU0yevJfC9T$ z%oG`Q2bRCpib}VP)LQlcw;BA03XlW_fVvbckmV<+T2cgANutw=k;PjB;5KEbz)H#@&vHX4wRP*QU^q!o5L0nUJ37s2i*? z6^HaK@{x(y@5JC5E25bW?>pw%oElOzkT9fTwA_gn@K>Nt%Rjnn1eU(|r9cqcHsT8M z`q1CiWBph*!*8?GpEvQ?=s2URtR!~Q69R1~imyNnFK@+j zkeHT@bvN)rpeRA6+5!=bg=_s}EvRHlK@c)OIM65OaU+W}CY)((f)sMq;|Vz~S*7@i z02fno2$u|`0QNj~sJuaT%&gQ5_I{CA9~N}!pB#)gZnQuDYBOVGW1$Sb`uG3jtJgo# zv~y`RF>qa-y6Zw#A;5l89oV0mskP#G`urZz5|%gRh&hHeKySF68dRTNj6 zozWF!XK~uN$D>1j$FB z>3n}%`nF+Vibj0zATKxf%~+5{Oe>2;N)f*>Eejzer=D7YqFsOlR4qa_=8Ew#&}_v@ z5P@;K0wXFjkMjV_V&MIn695BMe=T`O#S5wOTbwYe5iGUt3t4Vu`)ZCIskSdOBz-Cv z+4m&erQueArOparW671LcJqAr?>_idx`w`(<-@yGeY)nv#r>U`$FQ8G+>@Vp?%_g1 zYhFC;c##cp`ul@B+czw{a3<@N_)n+pwvSnsp9gE`6JI5cP%dOyHuDBcPOGm>43#IX7?qYFz}b8{ibn3hDwX01^-}D^66o_^w{2x4vm;oO-cpA7JhZA%eiE zVfI2|xJc8L#QzLL2W0aPtjC|Z3XAct3pTMU5MNfTuB%Mj({}G@HYEzjfJvYt;ZV~*tY8xXI}<{vy!?Uc@0)xPLZ7Hpc17#{|)A*s$>x9NiUIW0TD;G9(5 z&wN-myqo!~`+Gk-3kQ|wt*ESm2aa_kxw85fSBPpmU-p5q_C7|{0%Wsz((TMisyra7 z0KB_?7SAA0x^V5P&BjTgL!~pl&9I*2j>sLMrsD; z+F!Qa=D0n`OTvhPoT`sGYxn9wPBf5Tf>}6U=g89gk=>dJ&QD7JEN6>xXUee?Xfrr< z`lMvC?3o#S2_qH*!N0zC&9JMe_3FvGF7xj@6MIjOypH-?QFN1rxW;yn6pUsSomVw4U!ERcf@US`S-r2^R80Mg3pNx2AolY`Qqq-06evW}Ath-4O&~Na$ zwyF-tz9|v#RY~|mFh7Zu9rrM1_yw936 zGrf*^Yh?2LEI8ewVr<1A>iEvlcmIU(wFvq?U!~n!DN%2mgLXn27LTBcuB^OaWbOKj zL<)4Wkjze;a_n4wKmr^+KAZECdf!;MV9YWV1N_KA_0I)$ORq>YZW1L0701j!9E)+)A6yEoC~D{OWKDClv#|Lw&a)#S4zH$vJU<(Q zc@S~q4W7{!l|9Q9SWlJ8CS$KywfSIx&i5!HIs^>B3)lcfqlf50?RKWpCwj3i&hA>Z-DJp=0pFJbn93~x*cax`&($9 zx71~Pp-Keh^i9F&B+(yWYXBCdAdt}l{!di`2{IOr>x9ub|0%ZJ_5`3xxMBy-z*Hpm;h8PEfO6gy(7QnnjZU3<;^9dn^K5 zw{rWo+AYg|d=YPxmi=~J@D#-|44?ZC_JAOpTGqE;-x*-sT2BW6VqUx*_Cd!t)NMFfir_NYJ zr9@KK)sVv6U8I2!C8Dih|7&&M+|^)E@%}3}`k%VwU)%rS^Rc8?=#YC%!K^D$)Z1mT zBO2YFE0J^1GeFJ2iwJYxP~^Q3!P4DxmW#p@j5pGcRBx^|(m6>6;QY{`ZUwU-ZH^OW zrPY;h3|9xLD|pGSSqZQQZz3aZe1D_N+y;Yjz;NL-NM1@505Dm=0zVc;bW^1Bk0Og@ zE~lFNmbIandK}I8Dn71F9k{6$6uz7J{#Eat*%Lw3v>Pp`{~wfYlMFStgnVC4X}U$6jU!k+QfXYU(sTj-FaT)R>{5cx~L_KwANBmCSZ`r7WFc zF#RJ815!2yw47=`<&xVdr8G}NBtlvh4xkePd|*OcBw8z8i#%*ArK8@i`{kE4Cf*;R zY;L=_`_y9){wh+JWVn#JOR05aGdV}fyYK=cI zsT({&&EWYY9`3TX`sLpK=18A-ik{9PjL9GD%CS|#+ooBbg|)k}cTJDIr%9#BT-3T? zq>~%=^JlLn={c%6Z2pT__V!0XB!UE8L7VUcncD-5;S|OF>R?gr%EE21N#?Tw{rx3D zLDp1|(GGqOUly0%tqurF{^Q3IMEs5K@YQr-vV{;Jz(~6PZZ%ORFMRgLH{}GnT`O-1 z$n@rda7Uq1bu)#p+ie(3z(1+jHRV(e08v}w@x;P5{(L_gyDSMU--A?aM)>zGuCu?$98LJ5@?TlU79J{h~QMrOn?NGg$RDcL18 zD)}H8gAkfQ8cY43^S%DZb^LzU_nzZ$L(RP2ulI8~&&OHzoS^qG)P!GFa0?g+wb;Z( zy+`k)`;GP$dx>MWHdH#jT)Dn~iYP2F>oH9GIo$NCt^bp`rWAf#j@GLssY^T5pWSub z{C3_gx#gNsa;Rs>qonETiPIf6Rtf1l-_#iBp^GHcC|iZ6bIi~KqSjyQZFEjZ;mP}h7_VgoV)zOOTmMR?(geUz=m!_Or)&H4 zY+W~p|4}&5HlPZU;eAkCEYAzum`(w_#q^pGzj|*T@a?HP}UG2LtF4v|l{Q}Tb zo^~M$oklHutJ6P+X3m;@q?8`zK;o`P$dI$0KXHsS9hVdx!j_Ki&KsjVbwB z8Rp&3VKiC>f88>wTYXPDV&&M%FW>WwhqTI(gG~dwdfU!BsM4Zwl2z`Dy?x&A3G;C- z0B{U!Fy{q;<+W=9+6w!4CIa6q76S6n+aUPH*qHAw<|LT-y#M@rwng>Z>^bd}*rjv* z8EA=|$gyAS11Z_D)@VR#VKD|*B1WGP7=+b)n2YGm5Wg(xt#-1zvUFPP7I3frurWO^ z4Ui>OQ5qe$jpFIbhw)K?T`1uWVqxkkbvvTFOeG)9iG}BhvgzGjpZ1#*A_XC`dhBTv zWeTLAZ9SACTOJ2xDKd9BkS7hNef?g;2w;bM5F&FRpa`t%FD$FLDSyTs61|H(h3Nlo zCgJ6`kgTg9;>{xL{IFsV;!c)@;Z&Muz8XKx!by#dLP!3$)#iXLI;kkX-69LF@z5{o z&f~;5#3oktsoxQefeD+9bZ%(n-A-(Fq>@a*JEe5i@oDJnxx(u)0kXh3o;&FpPhM#} znzVVjQfF62T&es64@34DL6Vv^v0QWaz1TR^_4El+f79+Exg;6scK<@>mbyh!{=xc)8IT9@D3{2maM|w#Tq!7|Z(nny9Z|x{QVw#Au6BtUgBP;Ckh00h zE-?n{^YW%F1)2Wu2)i(f-ePvNim>_+4&!k~S+K94ko8lyFDH$aU$D)zGgPl=26xjw zsw+66)80qbB)RhJ9Ely+t{Bd%r2RhHJ8qlP&Sl6q50C|w;>ej2K@*RYA8_0yyb;MT z7b%JhtHWVHpYc|Dr>TOKex1E#`h^(=Wg+E)Ysw1W{u=ccE6csT3(YqjHk`Yj36t-v z6LM~_o4glheMf(h*qg6EUeOgo=GK$lsAD&C*q*P)YY6OE5uxdTZl_+GThEI{Ud;3? z?BxV3J4#=v8dvCj~DL23Hy7`O$R$M^U$j`zk zkovKwvu+Lue1x=nqEAHwV{x0HJvriuDed7q9crDb1y5^#qmMTwa(qGeZ%8zEYyYb@ zzj;<@Szr3wZ>#X{SC9e)7Q&}S`R(Z2<8;dV^;h~r6$-mCzyLAE1g6PnkStGGgZLC& z47O>wFOeD6plL27Z)K(nL+W6vh3ksGJ$k?1fJ?LSqP_OKEfr4*0c1uzBHw@a-+L*YI326~<>|E% zwig;9K$Z0*RELn}JkCAaP!clQ_dxJ~@t)Q__04|dlLGF>C-zK#mpAxhyZ^RX8dGGO zHUcefh{4j%oOO0(=H7p(_c!mQKUKzMniO)eEd!_|#8CBpsE+6h6L$4qUF?*~noT!b z+v*)@K?OZdD7fX)4kk5B4HJ+JOtV?Ml;dd@b=zL)6PV1vtKl)+?`SlWAW<`$uS|_V zmjib)9^&N{g=~`vY-&0rd!)8QquQG9E(P()J zXa;S^Ki+sz{?Cnv9}?RAW0HJQUUt%kO}CZX0Mx3rQ?chEbjlVlW=Do|;eLKHGOtMv zr~>&QUf<_EiJy*CJ5cQ*A-3c2d>7T`_43q4+5Gf*j1Dbg^5>5oMB2Nxd$DV0)uz^` zf3F@~T5JzAq}{%MJbz#hQn{S1kfj~D^81in0?jA?rPJc0qyN(RhoxVzdls@$P%%$d zd|J$bPRa%&2?@Q~$s>>I)&-@nzti(xnS6-&aR{P=$TOWZ`rIzY^aI}=n+5~=2hVAa zVzynsHwqhEnD*G`N5uIq?@wz`b9j7jrFZV)0OzNEhkGNlwPH{ zWuUw$v@7Hl&-9Yy7}&6bxR0E{9h~-Of*PNhxZFC8tIVgbYo<=%mAM=NirVHR1SFRU zXZbmIBP#!Lmd|NLhK|2GG6M~P30jxVzvyC%vVEK|I|TauVhD)1ATWK_S}4Dkgq6*T zkD||NCT0{`S3#D+m>v!jec5NISM0wkZO{vr|F>RnMIG_;k6(57wfNrM@jpaf>gPT8 zG2QIkUXSvsM-IyVSbXJsFve4DG{;!bi2h+L?AC0(PEZU7vH7bjVq_-EjE;(mZUq-1 ze^JAr;}~D6RMGtm0@h_=6aDG#E(koWuQ?(AbnSr0o{n>c)`bUo557Y8ATsSu7r*Qh zvUI$tfXtUEPTjrs`m&M7UWdbkKQ6n@l{+2@pNB`nDEU(T#1EYiou~`KtfiWLtbhZB z#^D`?O;FN6|lPkYwKPwtMg3LlY$5!|^Y}qZOV~C-8663k&Ul-X_YO ze7vPC>prF;IMh~=`e7Ti-&<~eqNj))*>QUCbTZH$ z-Ax;V8-51Hfsw~lU>&ugVQc`94J-yVW&}~tUenb6im0pnh$LYvE*cEjha=+U(Zg+k z3fq(v&~`B!cVE$Yj9RB$bs=haZrAW!KZ2|`A>s?tamUii;INmsRdVK&3?;m#JqBQe zm~OIVKx&0tcRG^u>i*=fpF?XsYnMFPNAU)G$H-HQ>N8C@2Hf;9u=m5tYV5K zwt7#jaY~nZX2Lud_jWgB|M1Y8@aSha7yYCK(GwDN&9|?;tO~n1=P1-oJID!mdpcK5 zy5Zd7#CVX;OJSYa-v8mTy!_CO!-6zT98gRu2G$g92$_&6j|P>pYo;ca=45KjQ(RPlK2$s!o4qAt@3JV8 zQO2$Lmd3A@XddVHUG4Xk-fm`iMi^_1aeP1bE_sFe`e}8}DkqTpl$;`gBi=6&@p7y( zana5kDWDM0^oIS|XV{4!!9>yd*ToI>03@mb$*$km$%O8UsMI2wZCK`AXrzd8s+s<| za%JGt^c}gGiW^&73<-*w+8Xlm?%u5-Pw!^)`slEj$K*Ry!n6#Kj7JB=1P}!s(N6kr zZ(SIPIHblD8PgJc!{bJALO;q&K6Z(9^aCq9HS(_UQd4krWnjL}dx! z+PQ+l03|j*Cn3P;M0->Vnu*UaRfsVQPPw%*WG{Zm_y}My(r`Qmk7GqAYeLws^q40i zb`}0nbR%AR=KJW-n6H8NI$KD0hW~HuJA(xsj<%>+KYiqIH`31Osg&56ZpA1ps-5R| z-deL_izR6NlIu(q-LjoV9qXX!)ED`6%% zEPe?VM-%6pLen-{X0iTLrR?8>cr?~|5Ju=u=FLKskP z@CH|xF-2ZH1FJ=DgRG#*CWcu_aBUedv4+~kaE4t)cRYb?pwVne@wh1AX`3B&azL-? z?GcLN=E{bq75WCsoeLU!HA+5PXbHu5BT-;x ze{Qh664!B!Uje&_5OL;afIA`ZtlmXad}$t z=-Re3t?5}7vg8(xZBnPhvJ9P+6nKns5R(a^IVl=Q!6MC+4OUKC|Hsgrjk1jy_sfH# zrSz5~dkV5wlJ<5y^k1odD^} z^=puyS-h67a=z9Wi({ZRP0I_}h~i?hVCN{=#YS~gRr0-$KjVC=4ZaZ}*J3sn2jIR6 z3xV&N(V;vcaqg9Yhd$u@lQ%=k&ugpnD6!~ozjT6Zt@4_MzirS_-mC-3UV#bxX#) zfA*G-DQL(6#S3G@@-r>P;}G|@RudR9Om5P`w7}qTg$y-Hl=L#Ju9PVUx$rtz4&gC8 zIL**6r8HNbOo^hbv+i1H2O6)-Z-X@4B8hiWE=fyZvmX+ugcK9?o!vBj0zgBD9YJfD zBy17BWDKR7NY1%_1+w^=fd&!v50w7#Q!o%fx2^y0^e{PQy`kquyEa->y!B3w_ID}FfA#-n;4WWjruTfKuF(OZyYuxC%C&w;O2bS~hH zBR)3)6KHtzsSqwZw-Us(!THUPjF3gQASgsygcUn_bN%^H9Jt6#3~aRcz4kY+?4GO) z@=Eo?mdNKq&h0KCJ9+DKD$!@Dw%CEfIDb>~LlxQX!sJtie0Kky|LPOf5df62ud)yg z^netwn($Cd1POzn2;b!&uO?%Z3o1YHVvY5QA>|E&e$F(N^vcn)&~CY5Wq6qxBV86c zr}8K+4R=gSXs{5xfVpnY%9!Zyg#~{s+?sQx2;1PMHPYL^xi0K|`!fd)uspWy!)d@c zM+EowajhH1Vn5g{5JZ5+nPq)y{KsX{DTW9}=Upt_i{2P@ThEzEvnx!G} z5m@1Pmk+PvdsOrI?1ZtY*2EXit@xUV2{C`s^!Z)1J0cBl+~U!1M-|A`_ggdy^8*I- zg}@%~^<)?6>cE?9Z;VjoY{kzVTrN=VspAKQ#+EYWa%cO{755-a(NSq6TnYx)VrNwI z0nX86hIyc|L~ojc6h6L;h}$lrxGC{zFn{s6%oSQNGr`9oxLBw{g6LqVL%mnC{bJYe;S9&+3&3t zUFGVZMN558$K~^OcPb{tDO&A(yp_X*=;+$^Oxy*sTDtf@#;l-L++Qm9pb zW2V)&^HOn!O4D9@MXi53KU%XI$%{UZc~N9a8OrtAm9q zEq^%cU*?!EbTF?q%+|g|XzBzDAY3r9o*DW_Bo-x5wGjr9m(0;_GJZz74{nVZ?;Aq> zTuyo1e_s&8^I7bj;1ZE0c>Gy(!32bXWHUje7SsokLKJvA1l0dg&ePr-?jK1E;@z7E zj{!~JST7tIOt~AK_lu0RH8V%;p6vgC!@1Vf zB`z%OweJ&0-ZxSQ;eCHfOYoH~cKS1B!OtERr_Z0)krA#1Gfm`&{% z)Cy|b3>0IZ+M)nq_!o#w2DXa4_P-{>mIsXzlDx{qOFLn@g0AMzdv8PLATyD9e9x@< zNw^Fv9_mye$}*v(vbqw$E&mnGZvS7LQ1u}G$~i{7So5VvqHxanbgBvv+lv2%^+ zyO4gsHb6v)`g=v>LLy@Q*~2zrrIH}5wOgBVj*Z!gVrJW|K5y6h-CWZx%Q9$6D>9oZ zqF|Q{sQ@S2c-j-}s;nX0AqLC!P;f7}nme`zf2S5)M4>2UGaKC`8zzjoqX;MV^fs?X z7`RnO2}judEEXZM&HAnldT@46$L!@oNor!N*wfe(3D947f=j^w@L8*KL1zuyN`ZIg zry{PJv)Y+tuBjuI>1+GtA0@X_XSGwCOnk&GU2?WoU-IjufnhEBP8RMPY+I#_wESk& zy*PXsI!>ZHx)4dAfLy#*nogY2=?4C5{=nHMX z&!}tN3o?c)derc_@mbA|g`L%vxCQ@B8~XmuQ# zwKUp!_KxbZq~+V2=;s zkLu}o!IrDsZqYO^l#e05@IRaLZu=1V zGhxO5wBeobm`0qb+I)XpiAuu{J*&;5&HhKnx(pKoa?cp+g6qAjScTHEvR#SGq%DTt z&luzPLs7DZxl4+i8X8yZtJ2da{PkB=zA0i)FYyvat(N zaT@ZaHVe2Pe^k9*)qC!&gVn2jRtGzPwg(Z+UKtH9e`MiB*{!ivtwXos zU4&_!B0F$m(A=pISKdpm9E+jwE2KkSTV?&RXWa zYvannG^=lIYc2k{Den5v-ll%19b6V|_ym4{Bb24QIgodeEab7Yj4UdAY9s8fZh66p z^f=nW#j67@c3p_%#U&psSc<{GUIUkquot3|Tp3x>8|E z;~!c0a<=HR+X2j}+kM&pzVjXp!~`{GwCAjJ-+jAm>+J=8!GO;IGOZz=kSyWJ+dXgzpSfJD1kG#S% zs-w0EXFZaqhx!M6oR~uvCsrhIns0@w7A!rj!wo+E_wqga4zmmxPlx~QcI-{JH?Hsq zvz5oEnTcXGq#^55XC90f8Msdc3^P4oF-o#BdL=T6^4pl>TA}BtM^i|+nhWuyvI6>)-=GNWc@;wW zt~+H}@aMG?+*uhv{|6Q{_i2FA5An*^g%Cq-bs^=+s4*&6Gw;rZ+RPQ2@oSH^{;Y(b zt10{Qv(KTMAR^$I2XE@J3mnhvwA$BQ=N2*uyn5ZlMHvBkIZ9aj#g_Wu#$zVOPAJ(Z z+UU7OhO8ZY6{@aRo=m#B+iKU({XaRE?yT)&Oc&|KEE7Lk`ZO5@?7dC~`!L$g6yI<|bf7qM!*ZzSTlW!SGnvt~|r<5U`ak`9X~RqpnDS0kJMGN47GH`~g&NEmne z$MgI+np|)SgWn6{&}z61kP|x81~p#g8kD6$5HPQWb8+Ln$nG#as7}SB%Z_J6ZRDpgx`<)IR$1R^ z>oIAu;&@$&cwVGTnx)w$Hvv@aviuakk(nKH_Z_HjX+|XM=}h?TA0mr>6eo;Z zUX?Tbm|yc~^TlVA+uSIrR{Q$-U1qDG2Jh-FX}PS?`KFX6eU+2J{x=TB74pOTSWFSQ zjD5vMW=o3)g0cdg{^Rzm4-&M$m<9~RH3e1vVi@3kGZqr-uOM87zbS5NWPJRLEvn#7 zy5iK$LUQ@*_C*3OoxijiN>dUlp+r9KM-?J>sfv21@&7s65?IqgN{SSMq%M zy(uz$Zyt4BdIuh$5~j4akQ*zz)*@?+^)2}+;ov?^crtS0aaAAN#BJO+#ap_vxz^h+ zwHQy*&+&Jq_6wNlJ$iBf?dJVg(9xv`NuK5B@^@q+_XNrpZkMmi;Ga#~<+g0qU0%I& zLP%cx*MZ_M8veVK#~qZ}4y=PqM|=qc#R!Zk?Pl}KGdBZQ?L`^H+es$Lq}qXL?Jvey zPqA^#gn(CRqBtuc=!fg&t)hHJxkz2SM$s>6TVn!)Ub5a~wOT^n# z+xLKVayqdHqr#ncGSdTUH*-OskmYKM;QH_4L+U4HXEkfd2kPdA1M`$|06ZUWyuolt z+5?xt#l8B(AiV}vh>V9wk(`V7Ks65$ezYZ9A#OHPs?>#lZ_APyc?(LM463laHS?ov z>3u?`X!pg^PQ~jF6-1*TQ_BkXk5`~`P2YmcQ^z%(v3)rwb)pwsjvTePJQ>{zN!*3` z{!6w6KuYR_`g21kYHnGpCM5ngait5PN`%Sb$+&)%;>w|?;A+JjVt36x51z~Nqqwlm z%t}=#m80dHw&inzsn&IZdr+cmVN*Zh4DZ5)cQh0IU z$=`7C#UqN{JY$4i79q0+MtXPFXOkA%>=WJ3x38Jjebd7^M3ho;KnU;9qAwD_56xUQ~E2{ z&K-jgo;VQOKVDoeKncNxeD^(V}A+OuBaZW{??yhSBcNd;NdR0ohb!uchr>R7dCE5vG zCp3y9KQaf=4X?1XF8D?L-p<`B5nbICD z4&1HBC{v{{(9E=wOq}^4p;I<`Co~QnpW45%wBb9~na^oi|Lncks zNz*I<-~FcAG(JpVz;f}&roNp&3A@#H{JgkZZA;eA{~jGxT#@~LR$I!5FcuxaOZMeW zc$gshWhn|tcD*qI8%Fig-#}lYdo`s>hs<^~q8slsyvmBRMBh(TM!b>Sw(q>6xm+h= zLna?jyE(oO zj)&)Kqb_PE$C)Ksj86{3@?v|ai6rbMFAYV}65aEnXY?rCIdXl&uoq8eTRO>7*Fd$F z&ki68kK6DqY4Ej0arNag`7PC9JrH%983k`lPz7`01Qp;Nfk%kGIccREk;(^>9uoup z2S=_QXnPfpc(v8Pt@qgTG__%2R;&o9>hakjjF0J7-zMS-xzX$>u|B&{JfbN^$wa zdLl)-@+?uA{E-DQD#GQ-vAla655B$6m|n9VU~~ngC$Le}6H;CNLbx=zY59GnA&YYN z^~=x<6oBU5#_Zco!rIacU9>Sgq2q^EGSyhP8J#j;Rns`PRqSk|_kPB7`{NAlp%aF% z{ypnt6P?)&o&CO>hN~qs2wg&~yBD>IOht29@)tGjGHmx)*T4!vq^uS149wT(4f)gl zdrQH@{lJ4tg4P>`Kmo3*}fnF0vPdMT{fD$NZoy&Dk?_dAoUqy8z4*=es8=ZQJy9av4i`8<3-^nftkbSExz{mn1Nq90yw9hU32z$UzNfTh(d@Dt49&E2$(-vmsw0B11}aI!-tS&8yDf}mz`ZUxWr#;XbCYx$ihW<%InSPxyre%%%;y3!AErdD2} z#%Iw-c+C=|qcoXfl{Zd<%#~k;3tE2^+Z^zlv#c+m#fweOr=}-`%%tN~?@{?g>C|(s z=C)qg2qEh|IFV#Rd|_GUSt6o;;;>Ee{w@!o4FOB<~ze%6^F)JT$ylHlK8*1+5@TmkBxR z9O200@^7qs;vW7xp`G$Zs$;!DvNXE^eUoFM>bCJi-BDwXhF;UvB<8uvUUOoAlb*$L z-io@*YOi@cW%vE?*Z-j8|Nhk65- zNNep-+eD6d10z#=maFvzs>W9Za9FN?M^p z{GJ>cuuY=;#vIM~D0W+VJG>4G2wYE>9J$duSVa2D!L%)4rxz|4#-WtlG&vq8P94>B z4&0pM-z9(;3HcPDRlPaWW5)Cu8`$0aIxR#M`Vk5*Xohycg1P~^aUDm}1&NEM7*7`8 z3#Q~ z-B3J!&FfxYNtRRW>~#ss@-F#qRHm9oL@Dk9fp#ir#DqIIc;7bv5b=0$_`v7r$K)#5 z1Ox`v4L$Cpt-X1^i7Quw{EEF1VH=atPv)285<=MZ!zVC@7}Kv)S01$1_L1q%eygt? z!NV=^9VVJj-%w1#ewZke!E*za7ujNZJ!D;HdIy~(;ffnvR4K9Qeam`%8%~%s`SeZn zW3mP66OF>QT265Mkih|O8!X6LG%Fi;?5%PSqs188I~CiU!-Np+(w#c{U?BkU}k&il$fL(*b*T{f0c50 z6y0~b*#C^oX0b|UxHZzdF)Ja{T>totipr;a<0;q1q zXK&GcvDeB&|F;6-u^CHq{%mc?7kSMB0~T|_<)EQn)4%nDUS9%}N4{%nE#w&YJWo$_ z4%2Pz-}YvOVvLVr!#r-EO)D#N(;Xq%2Za}uT&6wpx0mnx6kAWjlYPc5I)Wa?_MRMWX*nSMFwHm{+>w%o{jHsD}F#nEQfEMb3lU)@eAP)&^cpRj5 ziGBv|#+8TdH?BIAcm88~^#^IV^m)$K3Qs%EN5-XNmM`e2Z~TZ}kFPIc>trtAoM;It$gFDNV++-8mx1mG?DnaGL%jz#y`s+uuI;gTYo>RoyQ}h)UPp+M z4X|H~b3VVrGesvv-j7Ug>OYj{0RdiOhixHh#PZS0}Nk-9$A)5|8+^aCgfr@ zo)|)^4B9si!V)9}b7tqRU2aBR)S`4#u!VT^pLtdlLJIVf_B-w+%@dC(XiGPx%I8- z308&`sCbq&%rY(C=r%clpt+HK9o@C&3u%UT&AL@j4jPRuO%}&9PiSjd7^91iWXjy; zuF|N2E-|y}pKOUPEDy{k-OLpP=jn}^`0UA=fcPnDpK>aF?sEOi(kTyTL{#_Hih}lT z)QL9H7XC~-GxN-|)FR$^tg=$U@92q?iFEr&rwElp1rXlSxQ~9mUYi@h;G!a1^PxF?u@{b=M1bs z(#35al_EMzjIwZ-?!nX`Ogl|`1nAY5?Vq<3pmH-d3^c~r{Qp#~PpTCE?0pK9_XQOa zFUtJ}QTgTnl;6Gj#i_nk{0;mh8KLm2QnCN?^=`Gtv#WM4Y>r^JIW?D_lxP&1Rp z=nvFrU&hA?@`rsS5LSoexk#VY8*Au_*;;y8;kdT*-6^-I)T!fdo^AVC@drWvw4T@w ze1g1B&vouDIiH#4$K1@xUbLOolYUQ$rkoNE9)w_T)7WJ2WY^=(`wfGdiP>H(i9lClq+9s%9aaJFC!_QPBIbZh^y^G+^>WN5F9 z48%AAU(41sNB_)-wb_5-1iQWQKPkBnL&K1N2I24hPp9WtgcK zdXalU4|)zWI3GX`VMI-cT7{9TunBSka*`ifLk(F=`R3Y>=#L0=t}@q;fKZzu`qcD; zjo1W>KBOuLqkxDIg@*A@Yfmm57sc)4JE*}QkN~PNAz;)dg~bp~)}p6#_rB7dn2XND zNp?sdg9J{j?0r+G?8TYDe~^@`K!XFrDWpixW#L@I&OxD#cc#%rGjPsQ|Fg;-*Z!=E zZn!i1f)z0rfI|VS9@*F9wKEh3H?}c8&bh`K`UhE@H@qchTW)xJFgCiM?OJ&BSBNlkz!e z-><)(z5Vy<=Fka^RuQGAzk@}^KI-ghwW+%pk5ZzE;%xaX|ArL`$9M0FR5=1f4&E79 z!J2XPnOW8Vu`bzzi-Wx2nA8?M69cyjsJW}1+4LN#5>Y6WKXFHNFut_zmMxo1K~Ykl z8%u1lGfDuCpJW4oet?wJ1EZQVY>%gQvUQ6I@oPJVLi;41c63eikh9-W255oEZQB=I$s#u_SG3acjX`(@5{{A{$&Op_f@e>Y`bW>Tf=~xI3*2B>y^Gny6Z4R_ zilIBNWFE^i$An+FIemE-X>_LN_+J~&xT)*b!d8)2FRZ>_vTseFQSyN-T$uS{8T|Mr ztG~Zyp#@Sp6RVkqZ{=RqBtrd@#<|L4S?N5y@u7D#lQXWbsdm$3ljUPjQ8#YbV?Zla zMBXGvL6Wbp7zEYy2m#c_n7c!fp&*kWHbr5^Z0qLT1yXmGZPbmsVz(m-8iq2%br>ia z#&pT=U%FVCWR^T*TNOVWVTSnmu{I%qbfbl(dA#XTavX3cG7{IQ&wJN4VRgKwTgQVF z5F*PS5I`nVh8oyCA(t5DFGm3bfVf4}^d~(9$g)zBH3KDdPkru_KkYZp!_czoe+@0C z)usB%o_si|l{~Oxz^~TV@)6{QQqv5C!!{Tm3)w6Och_47oA#`9JQev8WCKa;HMg13 zZ=-!%(CuM`--zQXstPChNpWeG4*%rD_%by5jgYF(0-njTHF&Y@A@LuqocoUC#iq93 z7~f|#Mvxa)PRkw_O>_D>b+6{rYH!6O?NosuJI`aBmC8a7##y71;MI${6R)iFz%TJG zJKl3GWtWoNckF3+qTxj)OG$;#g)yx_y^9|HC(SyJi~21j>veKSv9P9!;%;f+S%P(x zbvO40KxW5ZuW~o)3W97=Yxb9kN=c4pE}?vj=yV27N|h7f*qRQroMp)66~}3Og{G4X z>1pLS3~;elC-7b$3m;4$)7pGye1E}%@}Ck_EtYA-ctq-!^uo-Dn+E`z{Od-rM`0SS zXa{;1dfMnex;5WB>64W$F+8r<*k-U(dO^zrxR3T=63p9Q1ZUoNtGwEjsBf zEsST;gC~=%E?gcT)}mu=hB*=j2o~pTPkhYK=B{);5oTKL{L_f&C-*PtTRo1~(XHsvU7Oo$W8S7l?*3jSYBI&iO4p z^HtT%aQ7RPTK-j);@b#CrYyNT4`w_>0=wbgGqzpo)vioP&KAbSa9O5UHVAg#?-x45 z?cePl4{*r*1EcK!J!f=1%ILbbr^&`qE>J%vN>&Re4gYuC9t*v26>@u{#EI(u9tH9% zR>C*eijJ^&FW6G>#(yx)X@A|3ZAM2@RqYG&tI>tl!n!rQo@YcYpUyh(S3fw-*P~N% z-(G@Ga)ifI!Z3GZ$AxAvORV({o}6^FF;+P9SI+4!Q(7U@Ot`K8Dd%o_KQdp_*pL`o ze>`4+T69jb;R|3%(yTY#PJH$--^5%|?U5?18%1a~QV^y300!P>7@NbyfR^W2XFq-G zLUQ+oaR_nOyOEpUS?Q=Bx)6`*XT)4`ioz{HDN-{y{#XjZj4yG)r41IN%R;tpejGypr0Vl`lB z!Vje0fd|S4WAO-*5#3||F*g4do(XJ;xB4Ht+EkxVL}p3c!Pdoexo!HCvfo=@{5>Bs zzlm}tWyW#mTDH4R-$>*i#fovi#wk*t+Q96T?%M?Q^qb0tdJ|VVmvq&Wro z4M1a5JR*?=9_%9cGEsqbr-B>gg0;EDMDj9q)PEa`o4J#R-&NX%f7syCxeXKCdRXJD zh%BXYgD%lKfcy6$H*+J7J4wa->kI;Es>rBE_BJtlm^>n3p<&a@+O42U3Gfj4w(wF6 z7x&LaNyF2}AW$nXHs@~O9jJKGnNKM)6d2IR^ibtP%I}jHtCtCzmK&3}QT>?Gv6=1#Gcq{Bh>M9ES(M43K9rPu!0V`VhfsxyLKO>lWOm0080x_ybS_lt=&xJ& zqelzcay%)Hc-yw+J^MWl{>@;F+Q^9Yzv^Z8T>%!JSf9gKVy4*+bi9CKs&wB^xi0D9 z=OOX#20|uBH!S0WNZLaqdyB}(2RVHrxRKUIVSo@0?Mzzq*diR8PUfBL8JeBr&9HOQ z^MsRJZiMEaxe+Xc0{~}R*>;4Z)uJS$47&(RC97N{gvdh2-ve}_?SV^TkQ!L_+4BOy_^uwqQd zG^FH@S$DHT<J+ z+-zrsdM=c=GzczXcgns)O{*5rZUU^>O20j(aZxRLF%!kvu2^~DUx*kbGax2d_*szq zC&v~o_y11ZcRyqNlyBnpv#v$4@gwsNZkgSeO7Bm1%l{s$p_m=dz1+21t>rDpq#>7{ z1Q!|oi6<5T*)^sSO(D5#YT^sW9p`)VotwVL#OM{OYYq)sZs=xc|OsiLMiYeK~m@Tk-oleI=6Y)yKDhtE&Nf^iE0)Tmg#l&~KM^Fs2EKWht zfdImiWGX24V3ki4U`~;Z1AB3j>ocqob2;^6fA)D=r$ldi>e^lX<@c)Xay%>2BCSxA zt+Mvs`efbRscc5q=2=#S`&Ue}Y$5%q1%LZxop&9LvQKPv4Q<*rrM4~RIfP%nHGNt<7S2BHh(-Lm%>jjnt9udy1T zzCf~yWtU0JqKLH9`{7=P6Pp+Xz8KD2kQsW~RMF%xD7NA~_m6i?HeF2k6$FB0&QkhM zU70)8ds=QvQ#PLSwXFA5Cb?@Hhl&>Elk2ZOoV@IIK9}NJQ%t=UkyYY%&RFkKptCZx z8{G`ECpI`Mrbw&p-6+|!>Vwsd&O{jHz;mcfuD)IcNq0Lm4+l=jW|jxa=D)xg>yJFS zv1suE)(ZcdMOiM6bD!4qLq6CpFY+LO(Kr%hijKBaM8*9QSd(?qI7BC2;4I4&w5vEl z2w=XtgHDNvkoA|X?5=Yw{=!9h7YCm2^AZ(0Q5_(JJL2!vr9wewBP$CDFf|Bu={%qO z#*a#hB8AtEI%u~hst)vI+6y4gIxl~tY8S`DpRVvNJQ*7qu(Vr2>7?HU)^oy1spJKZ z;`Dz;=F}(gS#bVI9*jmS!7I9%MdXujy1QvunKD-Hmv40Zh1x^UAHwd4m)l6$oj(4c zCqE0yNhd=Plsf7ODdd@m;Y2MCE~1&eIghu=@7l+9Yt$-zUAKcjA+@ zG+X@NfOxkqsoeVIX|IEnGbSirbWcbL=dF1wDa@N?;eMd$`eH`lk$8TOI#Ie#in|z( z7!B#}@DALnv2nDGDIhlk;RF#>=l-$ZjVGuEavK_k(u9|x{5Pd7VqOL%hwz3*`E^4H z0u!7Mv;oLMDa1+1wDA8_4YEgqpwy_GyNA7U-!wQZp7vPkOc#Qh8R)f%%>|0U=qIzv z0SluF^jVDA%f;jyOv_+N&~1pAwh()qRBFtI9&WULr%C3X=G|kFb^6q5(caVh_&poO zm%HGheA+M)oIxmzgAbSj@N*N)8BmSLo&cOw+j3?|{nfLJMas3JAE-jpe0!4kP@?2T z%E=vfrd(rjA)lXpH|s+i^_?FH`-fSiNxDLNLOC1}w)|sq%B?&)3T#Lc3)55f9g8yL z5J*}I@U~S1d^-12cG3v7<0OUv#o4K`mI-ax*F)rsy8G3=KGoZ0Z-r!u|3`t}`Op;| zn)Kj^$eVa%Qm=k|2pfv6#HyZDGuXmS&z|iF%(F67Nem4?1reG3N4z5JKv>JF-jHqF zz5D_PIZS*)(GH{|IUuB;hG6*p&8UKu+u^d(d>L^SqAtaYi2}fEp%@@f>pmbURhivk zf==dd|2-vAsUc%q-Rf(L{;8>Rkd>1E^D|hNAl6s5J1N9=Q7?%Xo0ZPZ1Faw8QBJ8c zj2AYe%@T%PX%He25Zust=VUg4&M1R~NPIk;fqRM^E)3C9Top!J0cCLtlFO}{Jq6sj z-MIg(QYi8a{vD?cJfVyaVIQF0tL#L)hsf!62^=~}o?=MCO2JyMw;N#(-p)J~x!}6Z zwPL_eI5_BW4>o4LmtTumi4HdXa_usdCmswKTT2&Lith7g_6^kY@kpvmnHuB`(q=xQQ=c& z$xhjGwr2vvKNTyLmD?$7ZaKw!&+rmyS88gk(DvxYpDl{Sm6ltkjp;IY`NLhUCGx4U z*{{t`8r(Vk$@olQV4p?JMp#(=<@#pMrHCVIF1MO)J#KP0ZmrYyQS_RZ?(;eQBhH;M zeCypH>wfU#_Zu?tzooW8GxeZ#jmZS{>r2C;wcM~1%h zU}Y9AFq(BX4QLelW>8;1?*j_amzp$P5`HcWkE3{7{Wh^MI0EpG*afdRgz%P+15WnU zr&fuh6TePVO~rAx7lu2FJ73cgw%u_kfifL2TsjW5EJ_=}D+yhn!t6WR>UZjEG7}%3 z*`UX~qs@cuNTUy|2Xk&x9wy)B0&pUPE7${sFWaRN9Z{7h?YB~XX681Y+ zW{5+clmoQxwck@?f5+<xe5-3SJreHpb+j*Xp}%+W!Nl4*537(!L}(H3 zWZMu%jF7->sdBF@2=VK7++unCV;C({=KVi&O7>*{I|8p)c9@w=qT3Te=Pp z_#Q~f-xy(-9ba6!`53^WYjvhSE*BM>qlLs3SNv`0%yd24_63M=|~ zxIi{OkU|OwTWRog%Ab4lQXH#LQaaqReQoSd(~Y7i3EV!yO_`qarYN#QRK}OriWB{~ zH--u4GwO60b-f2xDCaF|-DL%ONFIeDwqIj%!hRBja29$GjCYo1d904L^^QJ5uBloW zKK-IIfzQ_Y|JZu-aH#jcf82VqbSehzn=r=GB1w!%QW?v-l`F(p&VdSDTql zee>_^m^Z^-&fQ&4td*lxbpqzE(Y1+<2Mrv&5>&$D7RFj9Dy)u`594$UIhTU0vcZ?+ z!)C@JK@WW=l8}Y0;-m9ib-^-MuTOKB3%nC=9%8!JTpRw7g|;#m<^O3^$!`OK1D)-x z&W2d>4iLo&Kgo_O+pz77Hm{IeX|>Xg5y;+%kU3ZYw#$SmnQ2v#&1&l!WZGf;>+$32 z!lU8)#!$$wIlL`){|Mg7U&S1qLCQSC8`5^F#+w(nVX6Grt9O33;`-9D?4O#V%bd0Q zdUfA;m%k65yL@}$_E7KMF*7RR>uuej&a*qh!ZSo;R*x>NU12kCRO}uj>T4$RjTqu~ zUmv3+dsu`q{J-h3$K{Q%o;H0mBqOa;SR0>P`0ZH}~*~Gchs_JU` zz`2D36?7w_EC3Gdu0TGHzPIfoj@JY*+z6;oyz_?4jLIM1DVh^5NgG{V8L%1CTA5nZ z**W;4?a_H3V#_XM)Y9il1M2l!+x_)wYiwZ-<%~?iy>YL$(A8Se=G(__+8LEAHV|b_ z4k^*?#UtDL?zN$v=C`#MnlLc8`Y`S4;``^_>``$_`EQf`R?RcVml~_oXL3Ja79M)bsoK^R@@>zil>cF6;M|{QZiE z<;^>N@JND0gDHSuhHB4b%HFIg?x&s&;qRLytU2Fq#oJ*5wmW_jp2J&*p*N~OJtd<} zO|wgk8InjkgB4UCgHTNmkx4_XAbG~YSpQ@X`@I4kLnl0h!=F^N*)xWM>??N5#EYH7 z?-Pu_*p7=ctQdr1?0RCH?_3s&^t<`uH&Azmp$TPI`jdTkl#z3{pTbG9@j&t+=0MJa z5=A*(FCO{o5Qk3WjEWPlx!G?=%wLcrgoU8L6%KC5b(jE3$BIPIsb0CV#J%Q+Juf$) zdK$rf5+4R7t`Fg@c@O%kS{pG$!|HxKatWp@3oP$}hs%Ma_=UlMeTh{yQZ1i~9Xhro zT$+2r=s%^gstK|Ffp=Gb)kzx#QF`ryDZO_xuM-69YK5QDerBVvTBnTA*9P%c2HMaW z&Ror^im+Rmub=E`@xs%2$+t$dZVgQaj?20>e&ZEX9Tm48?^zxDvH#~~E8MlZ)t+{z zf)f{x+dVv*-RC!>);b>Que$nOXDL|JMVFJ+G0j)_o=CeI+DTlQ@G9?y>)^;dNGFZA zUD3ww=ZtpwL|Bye%eKIK;FhWwy%G_mo zeg1RDk-vY;YHaeuW(}TwnNGj8a5R7Z#J48K4)R)ILMQS18R-*DbU{p5o=Cyvtp%ID zf8r@v{Qj2b*1~u5OHmRCrQKvx43A6r06u zXK<&m{(iwLxk044Ws75J&Y|7;A@Cx<^24Ev`;SMaMwXOn#V-Aw8(1j-j?32&%zjzHw#reuQha>{QY-( zZWGB+%LjsRvqd7FlJ|~H@1vWhqa{IBI3I>K(&EK7>R>UkMu`{Qs!rpQ=dE#8yknvm zsBC1SC5=%UUGFo|56t2AIi{y6&lQ28#tqfQB#o5&9ISS6WQbcIcaw8_Dg~%;oZ)jP zNqZNMqmb%33OecMiSXv3q{BjW(72lS2DYEzr&aB_xG%^u#GqwC&eXrHCgl z#?-0?t_-c*;rM8~)WyyEk)?Xugb2?@0_LY{ZzWBqIJdB_8TNilJo@V6)DgeQt8L(B z-uji`w9w~sK@5ra)d_MJLwM7j(H3QYLCJ$x=}VFUu8TO6YmIDe8#)}pIAq0#B`??H zq<*k-jns+Yin~GSD8D^f;Cb}4lG$L{Nfg{|UK0cUXZMBc=JsIX!NuVEW8!pQCsCR1 z%lOO;yho0=22yRAHBXojeinh&9CMXe`q^^9%Tw^ru?LcBgA0iyk=biC1=+{M&kFfV zAm-|_A0=={AKDi+U2ATwG-C^wIn7Q=X%s{ksQ>ZfcZWNV)*pM2Oq^Wg3!72mvP%p7 z7L}0BW=#@-HMnES5lA-UZu*41q^0h0sO_S;6p@NpY+-IyJmh*e?NFpuQ8MsyG;1}h zJd*Scopz_m@8qB!yTz_N=V4V={k@+Z@-S9|!Ie>%L&I`ZkAB|pWCblAmc4jgL`0Zj zpXyrX|MZ?uhnkburte9_HJykc%#$(H^5Jb``^5S6Hl}Qo{d!0<)?kaClw8KdxEB?1 zaX+Rh1Gc!s(+49MX}LpB3DOns?X3evI%2Dmss z{fnHeDjO(ueS09|B1a&x#9fxSwdE*iCO3vLj@NzLM3Gt;EsaHdb#A~+ap3PxP1^5a zhgpk2w9gs7W=)f)rhK2+Y701b@po<4$b>IPceIcT_^Z}2&!(^4lQf)57GGGRKN=eJ z^7(~ZZ>_Erdbzo{vh7oD-+|{z`snA2RX0=o`Bq9z;R~H$Q5wk&8Oa=ki6yC?cxf1a zw~xFM`67zcu7TLi5VQu|mK#%AwodIl%&k;~&OsyIa-C2)fT zCqCVLrhzEXejT7D;B_qDs?8iK8}EH3OFyX07##4n!lVen9Ns#|{Cr4QZa_^2)J_wz zh@sXA7W(3FzMdA-t%$EVhjussh^GcrZ80`ZYq;8J>_J$v{y~+AIP}Fn8{XX4>8gb)2d-_yU=K|o4>Gec$dNcERBWBpjep9Cl?j5@>ADL zv4V*!!f1VF=4|)&)|TPMZFHmkCrtCjKf%u9lp;|lh9Tb5gd z;hzN|J+E?j$5nGld>2AqDGN}_qTu)%wY-2B8RBfT(CSlL+|ue()bCF%b_7l&GYlGa zrY*D$$YcAQ(3$O+E+7Vd4-*)XOok{F1o!^I304b7AIK0_pnIeWO5)q` zg({d#Hoj@K#6f@Y^0FwGn~gvdjs%e=46$0Y0_UVBIiDSuBtnSFk33pI9TtCGy3NcK zu8pQSrWE4OVtBE~&jz)#*nsh1W!>7Ho};M`tts`CW`-$NOa$$5A$31T)nqO_@6Ky? zH$RBT<|}cT`<{gwk4OFzpU4k`!%K6^wc5^6bsj(;cAiGZ2qz(zeBM$BJj7}Bf%lMt z%}HpfF!*F26o)Jclo0^Pw$VT7DI`z(Wunu7swNdRQq;qqkoXuKRyuark6P90ua#yF zxio$|ib!)#L@guNIX-JovrTq&jq8!6etRu3Qtd*g(>@tIiYkWDIOvW};&-q zLucM8aOD3NGJ1p;(7W6(st@Fs;~gg?x@=sTMG%#;3dD3)w(f=7QbDvz9}nQ`9$ zGc^-j!=l`1hw$ZfLClf^5g`rDtzM^`GH)vWqV{5Qh>_;JSxroK*WwY`Xi#gXv#BS- z4jtTzvA`kW_ZZCuLgxU145|`ljNQ``^0J=`V+}+?ri#q^hJe@4xEbKYUBHYT8B{XVmk`XJCEW z&91(`ape01=i2@LpaVK5zi1S$>W)L@lZAhFG)&aC@j8a_wL_M)^Z@kHR#TG;%>EcV^WQ7{U98G0J(3Mdh zm~c72m1SHWS%rxfd9r?khs!yEvyBNZAT!*N`Fh2H!a?HxjM@&UE{fE_&1ca9Y;Bhg zg1RbQo;IhdX@~QaKjH1fXusPZbbZkM%Wx$Or*s&$rjW3TY*jXFkZ=JhQnm`#+ z9XN;h?%jJzTT=K*gN9(6&=ZpQHbmfu@Fl`&UfM>ForsE$oredDg1>zs)v~tudYX{^ zI{iMy;`hEF>ww>%YX#-^B_)Q;I`W*D-zjN!Jt-6y(>7b2-Newk3O1Z$ni-z7SQ7h= zreBC=w_lMbZ35$Mf`jdJl$h=dNf20E1Lb0$>*4w08$YUNUDE4OPf!R)Q?r{S&T(j( zPcMG?GT@qMg=>M!xg~*K^lFjv)_pP3m=+mB`qL2c3sV-1EbNklAXSF0u;joP@PS^G z1)|p2CR2C;_9~|_S4LNzIbeFX?Rx)MN$vgOB?$z2zM;J9KD{C!cPfbp^EhW!es;Id zdhlX&yu&;B;6*Fto4;x(i?;E|lGb&fVL!Snt=io$;oPxo!=f<5dt{OImA34D&6RCT zsh*K*x@+%Pjd3xLK+Un(TS`BPGpJa8<^~X?KK9RMbpN##{`t)>Xo32x6~8@515Jur zRT{N7_^Srr?BuWNdvhTO&nb?E4#7uvG9Bhz{|X3`)8>p$AD1dk`$F+(&cTff$c1!# z+K`RPX^T3K4SG{|6I%$D@F#ODDXFqL=2tyO8;Wt*+~aQ4A1^E>yKYZil6=MY*jzUr z;nl-zGCmSp|0N>Meq+`a6vIWDO8Ax8V5XtXd!Bz-X5}2(*e9qTV6B1)=+rTR`(V~1&5$NZta|=Rw(LX6RdmMbSVhLICNb{{deNU~# zYf=+!s-uMD-G)l~k1cN4^U}4FT12{6;^-h^d)^`^-nilCj@#``DBarCxl-bot{6I$ zGkS!sK37V$nx=dq+lTf4So<)y!rm~fo8Hdi8xQV=+aF%K>3y_V&8_A0BEqzOC{o`@vvuDo^ogk>xWDSeO9>zGzps<%ddy_fnZ zkrA93#x~OwGt_t%&1O!a9ZSafrqk zcmgWEqJp#|ltWBq6D4M@-2&;76C*rZp)D0f>zRyw=!nr!>1Xcow4^Z>{fWM&IhU?7eQvW2C~T8N6=LBqu|Cj@tuU z(M(!@7vOy>mREzn*#lVeh*V@L?C40fk<&asc|$}L>9re0X&>o$ihMq~(fILodzba@ z!hH%$A`)TPPyt83F=^5jR|?ZQ>1yI{J*$VbRc{gt?q)$bXG?hMFX ziCBHW&9OgYA1>o#HgC~1oxYMm%8jJnPO-^^QXkxjj_E)nphTI$&EsezZOG(`5A>Kg z2^{EfeK+I;kc-&i;f%~0VkD6J%VQKH&DFaB^8@k#zUQKl60-h$y2z5iSxMtavbi~q zSIo%ePjl728vFifF$gA*g~7oJPA~<$r-~U593~z^JZM59Qm>bT6IlX%2{c(h&)aLE ze!e&hD!sTlM{_Svv&5ZqzhC+i=N6xaM301jCk`n)Qq#6r_!kl+)KC0utWm#tNJKtO zwY0)F#24;ARl2~sqJCs!3(!UzdJxpipN*yl=ty)r0sH-c94Cv3PIqn8fD()b zrdMe=KoJ#W#PB{N~zgWli)FRaf%*bgE>Vb5GhFE9PVK^VrhO{d8DvC6G@RE(c-}yprQ z`^?%)LdY~M3{tmJ2Qx^wBTx|HLs`Bx{u?+Plr=~>vS`TN%mP0iq*&AWE3oy4Tq z?!P=Rb6g=bq~EAuO>StD|FL=8rL%wYhlWn;Vev+c=bsznw01c@+&W_xxXx|MmHPq@u7K*f&8~2~#1UsN| zM%{;cp8tu*xcD6=upS#{n(3^R{&H|(*+uo zYKk~Tq$dy}#2{E+>pgtTnb@VQ%}HzsHemsA$L?-Xk`6kG*|?$%n1W= zBk}~U^RUCtnk?B)#idT!3~M%Xi!tZ`4B~wGA`PDwgN1KY{QGh{RWrksbs#(^rT-{2 z0iXRRrhpsLk-iaDX^0E@M>X?>rUreK1_y4%=;><*`59@}T8^Q>FpzOax`ces&6HQx ziSd1a?S5{aqQEr->$lfjZwONKHVU!->Ibfw!_eE z4Yxxd#@luRLnyEO`yrwlI(<|zf)Uh7F)S0k=<#mr8QkTRfx3}JgOeN2@Rr=IC`xZa zdpNI%cymIf6=^kbHI2{{VRAO^xogc3Caz)>wTwv>7<_B^@x_WCJ3QpAW&=?{EuY1p z{Y2r36IoIB@UFKO;#SSDN4WcWCR;i+-YvqS@Udmx^q%sC-uf#&@5T4L_8aGZTMGIP za)Tt61K55OtVvMti>^N=wQ2bebjrBhE|Pz>LEGT{-z!QrWdw`lctO#2{p%RV3V}#T z<-f~j&-k1S@U|H4+c{ONx$ct?d~>*ZMMwQDcI@C_X+nTX*`y@${+nP^qm781Yvj#x zEj+rer#^xa{nWd3lvvx0c1>b>&D^O}KU+F^D71(9HDQnK?k^?0wzI=gyn|E2&uVv| zX=~1ZChfYhGc^>|ZLQ(6;#p|%GOFj5T+q1JO7t%*BQF#6s~}IXpd&>n1eMbzR_X6p z55NwVBk+7PeAu@p|AAD(B#}L_1e;w~zB_d0@z6(d`R0UQW!islrlRs6pbG9JZO9EY z@!xcja|6?W8s3VLjTf}5i$!>J6lQjUm4*3ybFjpvsF*~uJ-ts3^W^!i24W(D;ppb6 zoBBA6Q3ePfsr5wv6&V_gE-CQ5Ll@Q~DMW%`kyDTA7Uh`XVVsto0DOebBiQ+54v#{V zl)xxv(t#AtK;Mnz9Oe?_k07Vn<7H(c19Ri0VR@4tM*Ha!LUI;3<>=0MX3YL2-H&Dk zG3Rj*Q>ce7rIGjm?DM{g9hUhlc>z)H0yL<|bWT{QwMvV}0o8B6G#Kz!ftv)HcPF=y z$$0*InX*BMYE*F2=Mp-Wuz2yvX+o9kz$0{@dfZppFYcyFEgtvCRcZS!h%5!GQspv6 zgWJ<|KT*!o4%_dfh#TJQT=`NuAFkZps7TYMA{Qp8n(3|<*|Y`bC`ITA)mMS>ISRrb zn!O|t&veG)g-EVo(n!mS6U_9AMSi=7H8d1xo`^t;ngTa@@eIlll@t`lcv0j4uOj~I z+=`Y#mJTjGhDtQl2)}NsezPEfI9P9Eyxz0-7AD{k`>kM80mR0_564Jv3{0c?vur=Suh;Y544Y8JN~|f%{+~Bw@#5% zHLoMthqPQ|T*5$8qd1~92T`^a?km5@6Bv(Wvb5f%1_`N!AQE4LnU)ll@|K@R z>i{gdUA2AX6LqDtAk^RJGr)&5?NG9QI648@wKWN9*+@~qKk{&=7dPph`S(%G`EU)G zvO5}6XkK6ke4IryKi|qQ>WS}hGO80{sj2qm?@@LpV_S(H%RRECV9tBHW)E5~)YjRS1nF>XEQosSl6@_1zWJ%q z?F09#h+L{G)b#?FAMyM>Me?|q|ef7CtDI##{I=wPU05{3eML1b=7|E@(j}I;B zVxf911Irra9hZ3)kqucqge3vjHppK*l1-nv&fiz>WjGhU4S2_wW87s?A85ub6Q^)= zsaCOogw@w8*~E0OxnE_A5I`=Q@gOjF{}r1)J8 zfWs)v>prSS;b-ejob?0`+iXTZ>P6Z&^U~b>j^*qTMpr5xpb<2_AHdAZbWC48w^XkP z-q_qR`0p>T*v*Odo_d%K(2b!K?Y6Q@*6JM)N*VU z155Wj7`C`lpo`;#G1OWNJ`vJ66DA91*FN0KJXEz=7sn*Qero;@m{afqKd-KK)vs&uapm+@#tdDN z;g~UK4=#$ocBtdPDfF}%L{VXG;%%9sQ~KHR5G+8?PO`hQoKZ!X{KcL5^Q2vTtfmt1@fWFe7i zEE-u)WRS$4!)HlqZf8=F-7IvwY=)UeVGT5Y#9#NFc^eG$hz%b7^OQ!Plb15b!4zt{ z&In81z|PCil(-0dov>Tqf~?dz=Z~EY@=ON7^^p4*$`SwqqR~)ir4BYu^C-*{-j3LD zhwW!@K{!rvu7HFXB!bNcU9#^F2jUpJ3iw-j0i_2Fem_#r)m#!Fj+UTbbxpkZeURL} zZ}+{d4WmSC(0jHp^MQ1-*c0Lopfe`ME78e{BYh~mR`|vYyDVbhe5Tt@=61Cg8a^%1X z1gv{Gz0ZutbuU6H4%B>52azomXD8Uz!HXY{_8^pXcSYKqUpSR}m@}#FvKs{rKY9sm zy-9H~8NL_bNB4N;(ci1XV|A(%9pP}IYO8jfZ*FuXeY-hsiH+Igy|OgFOYyJ=X4vIL z!Cy(fAgiVt2#nYja)%@BZXWf42mtY|VTiX_$XUI^p6Dd+D6d^AYGGnGrm?NCkWp+CD|Bcp$-NT%k4W z^A+pA6w_;Y4hXz&O50 zHbVa7l8i;eQS>`(GWF-#eRNBDJmEPegJ(um+u@YsA8SU@MEsV2gO4pTO9TxjN@Bf}Kx>*4)|g*KpzHwK_vdpfM6kXo2aj8*2Q%CPE}d z)31B}@J-JB0n|}mV4e4IU6g5yi4I1AralmTPdMYy{G=NB6`CU;Pk#`Yc_-5ig5D+M zdOCr)HPnJcOG1h06Ow`;>=+Wpe@RCag|~#bsi?EViBmlJ4i;f(1KAAwYQ}F{I7IQ~ z=Gc%$6GP3`sM*~IXuoK~e&O+NBX-C{$A>Wm9)ul6(S=~a zNx%GtyMH}He-HMH_l7j{g1hH=zzwUa^?RM?XW!WNNAtm`6Ga>TuS_Hhm3)0kz|uh4 zcHp3`VB;oz_k>+*&dqj)Cwi%etbfQVnXc_gKb5t1C9hn(IoFo|oYEx`#EP zoz5j8AtYx!WC~fgGb`fL!3o<8x%)~qUsEJUIg7G|g5(EIq&RQrt1p#8g71a5lpZo+ zW#jHoXmu5jqWS|B)0_d%$OJsYoyDlMpA<&NxFgk-j3^+@+MD30N-Q~m0vuEgiDIV4 z2OiA{qX*T;zp`E=AZgNO^uy~CExv4}IlO?Gp~9(c*{JJTYCm;%9LoTU9cmINoDSrr z7Gtk0Q&PLKh%G#&=Kn*UCNp205bLa!jPa(C?B~MgL3QfToQ}sy&N;=5!;N|AcWm{@ zoys>g+X`IKOf;dKVvQUDjIty1#YtID_|u06;9Gz9@mZ7$LGq$5eN#mg4+h=6c ztb*ly6dU(D%F1>ps6{NBsBMOU>?7q}BP=qmIR@ z#;RD&IPi9$A7#d3vNt+BC^mojBxFwfoE-J@~jS*aJUnJ1Lc45echIv z;$hk}ijIHVDDTAh(|g9wF144W956G<-ybtvU9Hi8dMLi;y$=ikA>YEK{CmH$>sCa#b5*lH2z@@Li6=*tdElDqq*5NW8=;k55bl*TtvM<2}JPzpOKc z>L)z7xI++8nKuC#*e_f$UCBTiHm;|-xHt$!92RDP02>7s9?KLTzXuP_;R;LUSO!=h z!`Q$G^xs2?l$$iY9;Yao3_kY>WA$(X`h$shkeR&I4O~O9sTF?&y4M`{XiTjZbw}*t z@m)Q?zf?H2MgT6&Xqyt^6o-VNy8#W(B=Z#la9sA3h%`_&6W||}UXR@6;9fn?WOP$C zl~p%!e!9IJXgD|9agqEEC!OI?kNWCtzt9Kc(E6uq|aA{I0KVmINE?pu)?y6e%`KzP1Fobv6(dufS2 zl(+cc#oE5mxPob*3?$aais@cIv!kz`YxSqZ5kT#ztIZ_spdw#?jh5eAUP>8JFdnDY zx~BqBkO`5X=%X_YDh-sWH)}j&#FVRByR%PLsqOhMaQHvu5>SI~;rfB}ZpWnsp4+|; zHEXK^z1xqndV7`9+-AgV4Z>uU{8kKASh+m+SQNtzQNz{#P0nk(w)9Etp%`lf9jNo& zdv3w4ljq!`+dG~ge(K%YyvM}EBmTOu@$K}b&Q1E97EI|WoO|pd~)?20qhZotjhwLs@*b34AiBZf5=0v^-^ zAV;~fi37B-1VpD~rWt)s&B~WC7<4T^?%NN$yHW+$H>kJ1my(zTg{z;eCa89t(2>W- zqPaW_Vo`cqJ_|Z`B@Jz4AWJGi`(W3k@~+pNXKqa}uk^=~rSrKx6;Z15Gn?oM2?)w+ zQ8j_szgNFnNn*;FXjuY^LzXRg9ErM_ zqcO$uj3*r5lN7%z-qdtBxKq3!AasYZ2{vI)*#Gk%`(C)&ZMLmWcf0k=_Ni6(o4Gyv zXgJL`Ikb0@GiErBh&QtvKHwZE8d_L?R}2D)ESf6xb$%Aq#fCJVVGDc0!vhou_foy` z$UTd;XH(hfAWmfT;01xsG0_^Z(C~>2wdJ*hMc$Kvdni21>4yXoBtsjm?2lmd+HtXF z={Q}P?YxqKhOogZ&>zO`C~10GT{p1hnFO_&VXfoikH-qmNlt^RhBz7TmMd;VHIz#A z&~bPF?!dD?g4iCf^pX1=RlTSiPmqiyfb>y?7R+in0%8@uaUI?RlO<%6K2y;hm3sw= zN#qC*U;^}|51#byc;6~IOnQC0XErv*AZ9~dczx!Wm3Hch&Idr#vmnm%{q%kHF% zM*6262WTE_d}FzUftS_?Mc50o$7bKV*lsF_YW)9jbH~iFMmaR|J$mTCv65%D9ToLz zlf&yCJzW#`MItD>>u#u-bAtP)EUUZcefK^Y6OgA(mEP2O#Z6>`pH$Er{G%YM3%BGr zSXuElSc`A_(yV>{kEiaJthXwTX-n~&ZG1Oz$bpQ1waZ#_VCKBip_q`j$#62ks5qo0 z!RVKqW98l6xp^q$iPgkF(EMwj5 zwdYg%PtM538hDjAupgjPo%cP=S`7&4`St<*2+NUC`bVw|USHQG0R`B^p779DgNbJ_$uJgOPNa5H_z4!0LE)*jZqkjS4mTpuhE__A)5t6BNyCvARu^D%nzrlnx+ zLmxcurH4!RtEYzt>ZCKQap8gX6Zjii;CGvsVWE!>L_@*zc&*lc+EumCEa{O1E&<=| zTjBBgZ0pTy{t7I##CAxk5Rhm9MYg#{oW^|p>-*du?#pvNX3dAiRfnVDbcK9ri=nhtgXL zP2NfmIFwzs89Y9$#S7Fk;~>XD)@c7F`O6AosBD9Th4J`9TMqKhDBe`Q##gm__V|D| zPt3U!x|f5$i5%97gK9tMvP81_=+Ey59U=AL_N8Cs-)z=;e8E(Q+DH9 zi^+WxNi$Dh#@mP^CTi6ch7{w)#$rHsojDHudY|9>8h^GmEITUW^YiopnnXm74t88E zOm0wZaPV_zGv?4d*v|1!% zkr#N6#YyL)c?HMorM^3RGY6yMCwl(IA4f8eC~sP|yzg)i>&wnT-8m6~AvF9&_T9yl z)3R#x&)5rsyc%Av-+}vMRr6zdv+$WmoLc6F)$%YjMkSxk)Wc1S7kGq@1M2Eik$!ZH z(13c*X60}t5vAQ7$Ixq@X|7vc4M5HVg%=H|n$+y~9eBHNz%Oq!g9+g}$3N=nKq29P zAWBXd(34dZe4__-J-&o`bzffIWkOyUiaFapNY4yR7S2LOX<#&F2_r1r3#L z@??tU8br1kmcO|_T5MS~@URZA!#9}LMliPWk6X4D@|MTkIhhTQsGzg3WOSJw zE_vj5mR*mlfp=4(PNk5)-plZ+m-%+KoopxVc{J!j-l3wO-bCojx{bA1^r90jX zIbzw&&4#J{?wjvkFjA(yocd4b^?zHJ2+SjA7Tc$T-5@+r1>W}^2-i|CO*hkkfOM5fXs!@9hGtpMkM44G;}I6248@Un z-Z5>>mm3d;M2(0C{1IR#6nF@b>_h_e-_k{fJ41!grTX!NOC~#oawSl zV|Y6R5Jc|EFjiBG-#}K6fDhYpHr%2Nvf32qLEiq3s+sBwOE_4^v&Ox6m<&_gSSOUk zNQ$bt^#$wLEEFW7ifL_@N` zP=#rzq9dG9K)`pc_!4LA=f-1AaW<-@PTu8%z_lEl=XOShGU_Qt%lkP39GP~^>THq| z2*`LGDI)0KG2TIowMToVKcspU+28MM4`Is+KTIS!w>*+b(37=$ZadYp|N6v=;Ffc3 zL(i}LXlbyL53&os0!{PjzI8V%!=x2<6`<4KxqCz8-+ZS#R(aULol6W+4J3@`)h;!@ z#!LqvIsECn@9(cU>7v~MoI4GFL^bB|Ufq0{5n9gwj;OZl4eNu9Y-MQAt(e-Yl!9TI z8{7Ls*ZWS_t^6TRch-+Q9BUkcdV zxaoO@z1dRnk76T%-{06kE+{xDA6ZGGmh}- zDrd9_`sv|m2~?!B0Y|hsC=1G_ddG;I3S*z#c?Z{{x#T)(WhoS^!?I*UC}J9Da5qP$ za>iMsf24qTZX*liv^se!FLnNNc^=5fB<)B<^l*K3Y!fU*1?+?R1;f*wpg}Q?)OQ|s zND65XQ;hp?t4C{JN>u>7_HUITHPTJ`iWFEh3=K4_W+F&+tSfrjr&J5mw=4-HULD*M zWCCjUw5GX@*>Te^Ruv;7p7<5?o-J7R)YWi*b!*rwe(j5}dOS!fzlN(9kQynj`k1LU zTm;(1Z?s~`!ybtf+*9FeO`7`CmpiEP&WNUY_R^cq95tQ5@Nj~C5x-Wa7KUgv_+n-c z_LoLH_%=!;XdQvO5rZA%^?M)2ebqg3K0oU2=tBSY{NdKScTQM2h-4qfk)f;32k#A) zS(4CWqEG*h(`%rx!y)T+Kg@bgJAfk5m17#`GCn?P6~?6cDlGmx4iIfz$VyD~t%}`` zTymFQk7?#|cQWhAji9Qy8hYf+Rt^n`i?(u`!YUR2@C4hLj01wfZ;yjBpLdY z2CME#;t@a^`l&LPYX^>Ocbw&4+#LRMD(Xi(u=91C>Md(YtVof?#~EzNmF1kla57vY z5S+or$Dja8)H*06S4qnz26HniXr+iKIkDNR0j(t+Lk?dZ+SLHs}#_wi_T5KTQ z4D9hET?styM^b!#Hj;r~QVlTf5QcKpess7?^^WydrOChT_6X~tzudgA-T0O89IM}) zzfX5Oc$qN8_2&JH9H79i{ND~eu0=yNH}I2ZXlsNW!mBHhh1yW7cdpM)=g3QH&{fMa zySKlK&a|_-{eV@A1ogn-?Ys?ZDKG6VV10-)uoY_0JueCm$J~QHuz&JM#wh7tJ^FCi zz^h`V&MMM}8&Sq=5}a@C;l|jYhop#(>AXPwj_J?VNS4+-*ech5grr`Hf}k3OVQM{! z@d;LGKqz%7hz)VN_tuJtu3F)-2MTm+rD*LP?ly@fyA`ErVImBZF%+l1qltxf3q_Jh zDc5=DqqFE-aEjj;=Uy<aK13-lDlIfyhV2X}(z$Ko;C}Vx&hG?^Et%X;0zRYlSr^ z`xbJ&Eo0)HYd-(cPvRq7_FS)0;LV8de~(0>^{8L(FS~;!4s}DTLGkm=0rKVd z5|YNml$AGY*Y+$Yo!~lz^p_-vFfi_)mti|?<{C>NDRPQh`80a{>DLJ!nGVTD*WQce z``mW*>Mb8spA)s71g%pl{7W1FRv;Hyy!?v1%;WftQdcXjS< zEg&a$ri9~D57*!NUOW^M@L%T7e~fZms0u}Jc(w(p)f`WD*cQQHbrO%KnjH%=mz})w zjNx?U_t2G3PUoT4era^RM_bKmT-7G#4TS*F694y@{uhZ=kJ^47HzxFI?CE8ms#`~I zO~|PTMe`f29#h?T@I)_JH7&OD)vqrtJDgySl-hQS#n9fL0D+r+UM+uZBFAD;VMu22dZ8Bci9KqM4Swl^4dutu;xlNU>+6@=x_f#HoWffTV(hQ1NH zDW#0%57M$JuO$(MWM@tmATfA&D^1iMZH|8`o1Nzt@40}%V}s5NfGWo7V!od#%RVHb z5ss(_;8pZMF(VuBeZv0FmjI4X5}>M#6yXGfD~E}bp#x0S9g}@mgvlq?S0Uex z!9>fY?n^iB7k;V??`&@H21ECA)5wg_qrGz4V1m2qm8(V<(Q3 zms-Um!*_SC5Am$OlE^m!(1~w&T|*o!A~;W(3|fVkbw&IYiwO*Vd)UrHoYQ8eJYokG zF5KU;o!_h}jLHl#tVOBS4sMlcJM>IXrPB$`Gj6u`=t8zjQHwwUFUD3>%L~EveY4zk z&RvN{j;Mo*cI_pzMelI5m_ZKRU&`f;dv7PDSUvxr1qi7C?FP%$Z`)-@ayl|TrvZD2&Uo$AIbJ4k=-aWz{<3t7MdqP-iI{<1j1zklKe@nchwJix=z6X3r6A!h?8kR|+_3*} z`EaHFbD#cuGsel&4i5c?QzFo36J^e6YD&!Zc&#T$Dk=^>&U5*6=g-*flwVoT%@$uVVCjC$@^6pvl*OZ;>lL=>?|-;#x$6QV&poAChn65> zR`|0mjD0fn`|Xg1#^h#NWc)kEN(gtwBZ+>WVDm2mrTMlX^74iz#vWe5i%eDX#3c1P z*2wgCpHpt_Q79+Ft?c6cwsD&*p7~8Aq8v{EgXbce5%#O7rOauj(!T#|jbho2naxUn z4x#rfZhD>!I`+xO)0)Z_G2D?+*AXveOL9(VaAk$yEhSS53~kxQ&2cRymcxt`;6 z=FS%{5}*xcWvns4H2*4^jXAs*%BDGYrYyXj@-=1JN0Jax~tX*QJP+}o^GUz zyZp%}#dqta2@Hr|JZ#>Y%?fW75#vyAXu(i`LM#_1fb+6R0t;3&2P9MtFKfA=_CB~8 zmh)XVt5X8*n{s&_(s(s-!N>c4HNspAq3)NYQ^5VCsM}MI?nF(BH1-J z_bC4Bs?-I63*4&NZ~=pnc(i@X<1DBS6POu)n?N}BkDM0LBZQvpus9smJSTomqwBZL zuc-_({bM(@|9&HUj9Iq+`BzqbxB&T&C0iw`i=P;On&K<6c)P`E zr`mB^k=5-%F~5+p*0Dyqr3+S6USfNrw+iDkOL7Ll6_P%akw%WVhbeWuJ9T9OYB2R> zPOWf_PaiDS}U8kTmd_XZAhX_n21Yn^J|QEzg99kem5(#Z`EP9$v#-)UBY-g=?2OVD8)(l2;6e zD38P=g?73dKiOZ9I`;Pqk8evm8Q;FS$XF-cSst6e{nN6)@r2isM9c-5D1BH+rfvj% zGn$e(y+?73NPyqUJr_QOH0<_cGPH?lumkLQ1MbU0o$2hIIik{CclIjMx!Dl^c|VsB zut9&Gw4(_T*f0D@&miM>f>reK{Z1%(>_L(Gd#;v>G#0aVq@*Q_(^4IGZkYADv2(+T zb#LOELZhR`>d(gU=$7c^MXRBPj)mb_!KoWZy(iuZZy)_b=6(UcQ9(ZchLmxUeP0cZ zOYLl{gOWMeu2fiZ^r}u&=~ixXjTu1L7}f!{$P*>VF`-oNX7pz>y&jdY$LV{jFJ^(? zp$pI+*eZ1Ue%^&J?omi{!W=xx>qr4!9IqNu+O@Zd?PLk95m}HMc5fM}?+#KJrO45Y z9jc^|8nXQazz^|Zxnms$gb7yGqp4CITvyl~kMF^h=klk0M(0Z`cLnKAe6no;n5!$G zqPiaHsDbSz)T1CbZb?<1dovfYu6*X3*wbPDvWR)rX>?jFcHGNf>1m>$n_$P`g3z|S zsv7JFgjmU?VP9Nr9od(6Qh2{0Z^(4TpB>+IapP*w*(vEMk`}YYXQ9ZfjDP6FPXvOw zsALF5U^@+}Vdgt&9@mIS2bp8m<*V~a*y05UVIg*T4lfQw?A8UrA+4K_zxrJx>yHwD z^FE;>dNNxr(h@M<+2nY>5r)53HZ1~T7BVWtO`g?L>O6&V@}0bjUWpL~B{Vf#^JVE5 zdC%)V@q1udge8w}a=P1phzWf+2}s^N81Ah3^kpSTE>K+tk+@FWRAT5962P(4hlPC3_{$-rkFP$|fYjf9R#6Y7Mv!pAW z%_pM6JT{hpY+w^Os|yTpRzU(j)Wo|FFNkC-!4+LpM)B9_&*jP>XtqgNFwg;4@(i8v zdE7fD)zN1CnwW_dwwzDl%X|-%(P0yq=r0E7Egc|_!K~W|Q1zio#n^$|Ioh#4-o${Z znlvZ;{FV%4dO9TC;M9*D1eC%*-%>g<9rqV7U=V>j>kV#quBV-Q`;MmsfLO_m5d%_d z*`)j1yr$$Tyvh;&2=bjcv%p-!q3?C{qm!OY5{Lw-#y57qWko#trT?= z1DQZ`*^oQw$2Z?!;UD_!-}v=H<>VdE9VE4_U%w62!q=mJnMxq%bg=FfHs`+yGZ~V@ z0btaZS3Nk#)W;2r{2#8)JRa)(egBabD#f5ZvW>kc5@V<+BW9S9P-sCBiY!B8>rj@g zW63syFpXr(mWq>7M4chajL;B%_ngn?^Lw20{r7b0QR6+Y_x-xB>v~>3PnSZp z9(iT4v=+>_$=Z$ys#C1-lg4XR2?p`a(ysC;a3V1JnzbasF3QLy@IsXO(ev3N$y=1bf#6nxe)=fCc z-@2!dTiI^)SFbf?cA;zVXdNGLmYHbli1!4F&TO3C){8r0yYb$Sc!5%O%gIGH@vG{Y z(sJ5>{Mn;%-i(&LodOQ-?ibOaUrU=L*v!1Gc3(YFJO`Q-$23O&?dNhCg@`lvruPqh z76>j2$5Tk`EYE!xP;p-Ftq1Y2oLB!6fZ*>m!Dxi`rb&$1_Xhij-`byGV%aF76|^9o zURG2yocgh1>?C>N0?N1O{Ep3)l9Zplrh7f}gM|5WH{t}fRCl%6b+Ov^*){%k&%r9) z`(iIC;yps$&f=66$hHkB!1h*O}BLK-SXM#Qj92F21q!-Lvka>`AlLQ2& zT&f(U@7&9->VbpBb@WJEj(O1*6kY%9!0nPF8A|@V`MYqVi(CW`0D00kgdhg3QE^E@ zygo@)jFt^0$0Ne_<<20$YFkCC7d5d_ih4ag8cy4HQL9^NiYAlPxJB5w!g~ic+m{_i zzUe|sh!|w>%P#v~a=EvMPMfoNkq0RPK~8KJN$Y#D?yc^71NT(w!3~&u8h}#a#8$Y* zW$2^)1DYfkLgamRhOXTXbg%diWU#|iTZ&p}T^zTSHiaFsw9ccbXjLcSN#S>B9Z-hqc!sSxe)U@%IJjL~fN0xp zql-LRxeM1me6-Tn)_1JY7t;}T6CdH#nmSoE&1zOn`Ks)!BMNR=V;fU&ZeXS~a~Hf} z^GW$J|6R39Ir@9<+`gcZ&Hr?4|GhgC#o6Q0<^4y~x8Gy%pKcu-DgBsB(aLGe%c^Z0 zyqyhi+hKIV9qawHFPLii12>eD`YJU9klTcD8Vlq9XDRWwt2&%m%Ac8pu%1nFyinr6ZpXHkra~csWt^f4ln8?I*r86`x0FC;ina+i%P0K z3kUGppXE|W>e~KYOkj?b?K(L@I81pkP7ce1Wtv{Uw>ihYSIPp^jeW^M);V2M5sC@C z*9QXK0eO9;ZUSNYuB!>wcuzL4>U$7a^(W0p23Iaisoe3pdf4(#1KGh!H`;VxV$<<* z{a_K?BPq+q@UnE%EqChvB%2gm5A1o(v(xSZ>_`5A^9lxg)9G79oedm}0CFsO(VO6zF)rXdmf#Gj49 z8_(+b3g?R%TNX~3i{Tz(;#dF^6~$q+LcKRNbauN>9t^KCLBOsx+Ox)Gp2!)5Owo}2Kga7*3W>`N@Py zApY!Nmv|Cq-{>CVfiEm+79RxYH<_P5eqpMkR~RS6JT`?vg|5j_7^>Y(7q-#_1MU$j zN$h`(wYDgp*^nFl4?DjXK;ie#lYxPfgqh8YDfTWd2W{J>Gt!wDLfxYB<~-#cu678k zw7ic|4_)80;ub(k^c$Az{IL~}JCVNJZMiYq2uywgSKi*czGqI-G3uszZ34%^1?~$M zX5vi+_CUwFFkiwE3IlDZ^YsY14lK<2br7fa?uQq;J_NR~ug&Yp!6WeTn?Cs@e9o2%p8b-Uoqu1zxI~dRyw2PKHs{trhJ(X+Xa3`W z6JjjB%l+mrj#u8k#L}NRs9i|Rx6;sxc3B>rOR1lz-AUaTxIW(fVQ_4ohhH`h>xakK zPj1Ib$K4m0dQBn~%zM5z*1pC&Iri*^z^(g4$s6K}v|!!yY-aGMrY?j))b0g}=fH62 zxugz=u#x@ldsdJC6%$FE#Bt>a2w~ZGMj-=BPc8(tN06%5a-z~M;nou_GiNH^F0~Kj zB!aQ)G+Vy+-nB{j9>2*{k1fR?cH<<@Bc)S5i817-o9geTJKt{TjGq@Q#N(!a5`+mD zY~qTkIY{7b<@S?g{A0I^m&ZQF;VQl%CI~v+f+E~!5b_?lT@`eRz(kTl2QK($fWYXg z{U+lbn;tX^80HPWAhMsz7>lUx?JpXj*zerBP9CQ#(#q=*IRrH2*WS6dTRz66%$Cq& zsW*z!r23ZOM=8*BYXT8NZhvRA=hc@Jxv^c@A3y@?oOb?o#+gP`^FJ_^ts4o&Gc0wD zrh1202dDl9xI#t*PBSj32`UtF_a8s>V)J92x9Nwz3BuJOLs8?vL%IH&I&q4U)Vf>t zCGd4It}+>})F^e()BuevLr=qB{q+pRli^(y=<1k1UwzMiN+1?@?m?~l?sGftcujxb$o(6|PD5h4-bml;qerTMmI{{iq*;xqYB-D4lI04K78vreAZ$RL2wk7V0 z)SPKyaLh#b=XyqzHFSo7zI)DgBwJW9He&T`U+r5VtonbliIvHqKHyu%&0v(h5w4i7 zXW<*h^8SGq{6^V+f; z&wkawew4_v;P4HLyOwYBDEK&*UuyQ43y*u9ZL_0t zX?jb)bX)cFjG+AGN3qT(FQ;O0UdwbDs#vrN^|7DdkjQY;y+&BL*R6!k?w8J$yDD)7 z6;HfhU>V<1hY5`@tBDP-U!4jN*f}>8bvNz%`*r&d+XO~N7KxwMv+wtAp$h#@2TwE^ zyUVS1Ty@~9XC`q{`{U(Tt;sm=>I{%oURB$~8*3FRFMFo9l@wmKN4^$h%_dEd52PKU zUWry;U}_Q7haNWl6A4oO_rXewi7A@sBsHE^rfjJ6^~&f;1X=Wxncf?+umBLt>@J@C zbl^w`!g7$-vt#U^@Avt8bN@M}5jgFrc^y8^&;GraS~ryMG94|r-KaRie4F@(S>va` zL!0+3p64V^fS39CeAk63%(!qp{^mWdr`t7HU*CwSrVp;Hh=ztJqS``+%cT4^fYUg$ z>KA&v&!KYVi5AD@r`N2}6J=yYY8}7BZ8kW<;{ce&*F{n&^zKc9YebYR1)t?E1*-@+ zV?Ex`to4TD@vwrAOI8yxPB86Q8kEZvVCw5Dl{`=0QLgE{pzOTSUAj$bX7C|cv?SB| z_B8^>i2@iglULUVWvF3_6hoQE%iuwnIke*X8pw2 zs>;;5WgWTkv7^>0>`_!;RujSlu}( zN$STf4+HgsNYxT$yAQC0>`?wH5uhx=7Gc&19zEws8n|Rh)z0rAzjbt2kPfx2zc1fi zK1IFtQS;aQhm?muzNCBoH6uyIPqs)?Eh9^?Ixh(`*jX{0@v(b&{wu!yoJ$p;C)oB^ z80#=EOg}O;YRTPzH-jSFcdn5OlW1WJy}bal84?8-7(su6@Gz*9Fl%9|CnRe6J8L@b zR*dT*J56OS7$gBl((NjJFblm1P(5VKXJ)(=!jG!gLyRvMEirfDEFwbITU1y-BX4=% zgoA`~2jw177zbs!`MCu5M`ONyUlnC8UD7JSUJx^h_Qbc+y>qYd+KO)?i<&_Af`LhT zKlS#jyf7}L=!K2osOHN@*0>|Xnm%|GM3;Eqbv1x5eu4kQ!q5JyDCKv{6vvh7w|Qf~ z!Ylo~iqR1?`dHxB10qSi3r;@&QgJ07SO5P9^sV-y8E5EEWnL@2EbQhUPwc+f z^*C%}??%QI9NM8m)(*BaOk}}pe$GFVq0FcAf3E8RG^R+igD+icwDsFhnWD;yCPooog^VNsl^w1^kiP(@9S{W%#s`+%)Xsnb@C;e3=Hzq1u)(6LnN1L0t`bsT~PBCVT2D^F$9opfH>8#0xX(OOe4?% z^^TTIGh7pmpA=h5i-grViLA+!1V`&tZ9l6}^qc7Fsyv|q={MT|8lZn{f~Rc0EG}PYt1)q)X%Dus2T2~=TeUeE{92HZWt%Se{VRq>Toxlm+9GJCVoq>{~j&D zPm44%0~kPvbe%$FT&wSd5Dj`HJ(tbAFID@Av|eDc4ZLc8&NgEoF**<-^54x4@BE8w z*-=l9KsM)2>~`tR0J12b=CDeuq#bJ5JwSWG{++qbOK}^=+AyWerIZ<;u5p4_uC^kz zG)OC(!d89j zlZ}h4hVL2FTK^e!U+XL>C|n0%f}Nh#kM8LL7o#byMw20wVmR`iu`-A6r}~jKY|^Jn z$8g$tjhiUP9Y^m4oz(gB;1%1Q+S(+KgTgY;c;j$mUZr979Z6R*h)XXjiXAk?MqM}h z56Y%Ke}5e&1Pa08>-Cz>1AC&EBpm!>v7^m*3TzIjzx}Lp;Mm*WhoTQ&IkmG%{^@sn zRM9*;`H8st>c>Nbn+|gg90~6+%Ns9ZcOuvKdzSvKh4sE))qz;o zT@L!aPm0JvYI$Na?by!cc_{x~eaCYMuY#Vu{^6ZnAN{1XX&&X;b1qE%IZ>^1`mta2 zSUoO+7|--Jm;^^u8n*vgXQ1~04(X+EQ3XT<>n;) zv2!os75|il0#9CU4mRN>6{>$E7tt$#Z$s0Atg*(tlL2F4-_9jZe?kcpMK0Gonft0J zsc5bR7VLeo9Kt`R{;!B@3 z#^U}4Xm?O8)2(&1m?!XH0(&*5{Su$$ze2 zt7Z#se*Y-*SU|L0)p(mG>11tw=QJpE3zXOT2tDzoxYaUhLqi+ySFi;t^;ys;(8UNC zU3}KWMc=s&VqMwTm=}`?Bgu-3M4D z@EmBxv6^YN{NTpK)dl zp02y)+VWb5D&VM<>|i$6x(N>5a=dG*H%`Xr_?A;%Gri+M;A-ds+=VdCv31x-aQMkf z&bUe1EcGQlU}Q$oppguV{0u*Zdho@*mCbs5O@%g;h!6h-m{I!Oot}JVVmL9EnERMe zf@LLP!Ke=HM{V%`oFCoL5#{ZOI`R83+`zzv%>IVbXcpQj-doM)N%n&#UvAwfG zxV)IDi4kbSAxD#+`}`R^Vyk->kAip|65e!20SLYWR4yi856DQjcx~AHQ+2#2I=Hc=87b%5-mz~76mvs!rOv{!d9Z*5f#M;vcY(&v`EKyC|O6mw~P(E!3s zKAfV3FoRywCo+i%@BDXjsuup*)OhV5|BajK2@)P05d)%{EJNHK;iqo+b@4ZF#*a>0#{)J$G zfbe{#t}Ax6hZ;`O(heH$JSnGjD3hqQR2*Y;@7-9S%w;0quUli;Z^7z%l;PxPtOGm< z@PlOB8Q36StIqpi~E<|K7cVC=+9K8*?xOzWgn>Gn>&12t-GAPkmv1(!m z{y=}fZ=~tK%xU|W@QTsuJx(dDA-tKvRvw$8w>KkEwyP&1ns#5h=W^c)8<<@DdvL!j zz_qzI{*G{xN97{sL-pInu`1^(S90;t!#Cn=dd5lvV$SVE%ddXP*WUn%Gd0qnQgpr` zhQaT$d#!OQg2;}(eL)pO)DH&dW`{3l!(v2NQ>)>VJk`|Yz#j_0dmu%)YA=X1#AkSa zpC*8l^9U5?3PUDGsEZ^lm-S~w?M^)qRp}IGBpy?b7c=6Mr2m*-l2Ybrs1P$Phk40- z8z8fG^xlKzRl)=rIFv0w61U=h%k!uJ2<-BWU^|ro>V;Tpif)*|qgvF)$=6^WHMaRJ z1{ruT=I(=tt4uD=Hg{EwQ`OM|szqe8Y=x*lZ)+kh0!eAsm!?{T2JtFp1XV*IJHt8Y z>=#>%EMDL00MDj^o6yCmN)JXD#$h#psBy?JU{w1`!-Zqp{^7<1^;Ikf3TCmoqwhcX z2u9b1r{C+d)7X88wHt6-#=p~E&GwOQEipe-Ez1nCPxL=P!f1*!@-=<(&OJ+ zPBG4MKZmjk@N4jl!ycFlqK=&ui~#hE$QQyMDF;rD(o7+T@2HN6b=bEPpJ=d_?8YB^jzYD)@U*8abw+8M%#;j9QY}i$M=(J*N9$ z^iFAEE=3@Zu%yFW7=A8fSaF(1$S#_l2B_g&RqNNbrm(N^J-?NIj9}KpAmzbT{r~5z zmX4rBp7=jg=FZWKzJlq@vz_1Hmt@I!r#UPYi}y=?lA#v6wjX*uXk6++Qh!~@SI4g$ zl2AE2@MrK?l_380^px7U2iFTvItM+ur|B5P(K(>~_Wq&Q*Dodh`3I?E9PwmXu~18) z;gbQHdF4k_ulW92(#9i4v}wMZlyqtFMha9sxQ8bYD~EF=;Pbyg_+D@&+fX=`)PYX( zj!3AaHz1}^z6{KO_!$YWmfYxomj_!`%m0Ic%MHqph~C*u11Dwy8C-bz@i>sbxeXAt zRfSihXqWAWaQ``%_^RV^TwM82@~&mLi<$9*D6MpMPn0xSQ7E(c4ih8ZXQ=lM}+lMgx9UF_4+^G4kvE_zV zzeVvQw6X5}1V4%N96(yooRb!cNkJ=qRe?dc*($4fFkPL0gKVa4IW68l+et{9uU-B8 z?G|+~i&Jg;PLRP&Q-FW}UWmI6ZYoS)zi5yF!MzuBm|Ct)GV?c4T`WSHP|UPf>a+vJ zX@n`KCG#n!_QUDVT+b`MV-FqVQ2cX9R}FR(rsPsBzhjo`v}$T!aBJYEj8X2xJzl)S z_vy;1aw%0x&%g9uAM@I<)8_bvQU6nDo<-e5i##|!2`bF}(wQp2X~OB0cVb%j2i#ESYFwdAW>DOopbkuuqLY+x_|vze6<=0MZWB!g zg_-r=LOVq%xVm3P`O@mWPs2wUZ~U4@y=lrdInnbGPeJWI+gtx?Zos3S%Up>_@3nhx4c&t9W<=ngPU}yu zBCUKYwiZ201cV2nr=+VhhiJXh(D|p&Xkh%p;g33`_M;MC6a^d2p*C3-wx6B6;n{7w z%NgB3JLO-+pqYzuz)vZK#9Okpo@QuLT}#hH2HN9-wkTLCcVBEVCr=QP3>VO)2lup? zyFBAdNQPm>{5;rF06T4^w?mrh%=u~VoBK)*?wO_By(s*7p3b}XuZy>z*17;g7Oa<6 z#iQ@!3vr}fWikTDgL3e0GLpW`3A;nt8y|#DAQ1lK{ zo2TJjhfO!ntq|J&w{>bIQjkJ z{Iu@0@BJ`wF7UX=pLUo5=GYzaUEDo)G(eHL9U}X&zjAi>ffG^ac>~IIIuo0w zd$osE&gaRcR$*CPSaqmjMi*5eXpLraX2S0K4ur;s$(GeG?k~7vB+R_eRv;E27IsOS zZ-7K07=pm)P8-VA!lgTdz~%dp=#fdR^VI%b)hOQIVTpX?9^m)>{x{|`Z(}-yR{7@E zuCDxwYHGV@1h$E%c)dimji&aNS??TPiM!qIea=@>d8V4b^RLP8%y1f`Z|JKw-B)8s zJbDMOg8TGOIV$hsua5bGXhgd*@C%Ie=plGHuxXtvrwkBgChG}SL=;>Z;3gD(W4anO z<8`cKp5__vAnJ_K=(mU=jFX*^4TLTK4NxPG-_qV6*f=}8k;w%_RJsb!6p7&;2UIdO z58W`i5?TJ2uhf`57&)!4Ox@Z3_SJ`h`iikVa+JJ~uk(vm$yOKZJKcj*p8Z;9J);hz zm9Jm<7(7tmsu9nlk~dJYnRm0joSGXT`rq=}bqq7)r2t(cbxxc%wu;>Zc@8s4htK-_ z4Qr)Qrm)qQ2kiLEr$m>-;jiU=#Dt7Tn+^_|tL4@hX^8?$jmKevAWs=!JIQepxYW$G zanPI0^}4xyS*WV`y>#RD%{9CB3+xs{WMmj^_iZ8Wb&aX7xqwZI;u^3o=`D2mPM($) zKFWS7+k$*$*Y3K^;Pt6+&qcgcB(y>C0;FVt%A(_X zxqrN*t1P$@x%DEddn%=N8};DjMt&KrB$Z=}y*Zlmn8AOPwZXKPpZ{XnE>n90O{>~< z_Q5oD15^h4gKiWZ*-G1cDU7(>p)#m$*YA4I4rPXRn&c<^P|;bw{=wm#|Ld1OKzMSg z{{1-S{6Kg^!yE3cE*03x!rX-R$iRm#zt+%3*GZ;}G&TD7=@-AYi|vnLFeed9M+)y; z?D1@cOEH$`caY~Zk)4$cc`?Dt7O2GlAmPcJ`&--k9+uUUt&Y&94#rPu*myoId%BP? zt37jur~Jo|D=#5pPzIdwWDH7FouVa-Q@27LRL*XdedSu6#%9u=IaUyGlGmNHiM)?1 zBE&i^L+8HKtrR4f<|c$oO0{m^wsG=j3Y5v~<2N?* zCG48nKYqO}`#G`jo2EMn^Xcg$`Am|q5htVzdNLFgMLat#4+L@Ol+jy}6WDP3AVcdBHo zFXdWtJT_b@Gd3XJA@SUySmQ6=KP#8xNxZp13ex7vnE}?@o)-E+jvyRj*q!86HdD73 zP74Z@kWT}ZPRSpVTApz2NE88|TyoM&^kdS#r%U5d`&T?XTxok^dkbqjF|xuDPs>~yIy=6J*WKV< zSyv?;+K_IKKRy;Bgd|&jbWI>IU!dP+f4ySx%l55LeX0ZnyVgk6c;!;-boX1ZIIvL) zh^ew8zP~6S16Tcg8k3rej(!jg*7a>t0((3hiA3~@0X_@oe-oW2{(s;eL;15 zmpJpW@3=|jEB3F|)LXbUBQTZVY$xHit9;AjrLl$+56cMMP)|sAL!PFKol}Sb@=u)c zc<{D7!;y^&iPjx0hEm4QA_tYt(8E4679QK>7jh~q*>ppc)1-Viu>)jGqCn<^+S+Y# z5vE8dcIhE{txC27)2QW8y?=e)aJid~Y~Ew1SDsZiwxZIOqI6u}S-M0hck}YKY&n5v z)_VPe!auG%s0l|CUC_I6sKa|NG$ZGSq)L*yJDHliF7L08vO4CwzNb=eaDEp^-<2_^ zlJ=RQd?h2|F^vUkZt7DCslo#{sFjKS<$s-L)6d34H7#{4-0cBp`R9MdT&J#n=Rwy9 zroYCC+zaXbqZrqL9jK%+_-W-bt7SzeE7YT&*WKFcBCb!ivFp`5`djDi@?&pam`98L zJ&y`Xq%Y?n`rNk%+CjKnviY4=LFgUgc`Y0N7Vi&U$P1uh`CBJaHy@CWF%=uc~xpGSaKDVAXl|$w<$2-B z2Fshj;gIu#t&$Rz#DBpM`6-U1!2Nx>0ahPZH$gt2oI2dAvL9CTk<0EAgtuTZF^1*+ zAtyk0OT(1Vrr$z4#j^=)s@e2yhB6gTMkA0OF)@lM54fBm(bKAlIbHaZapU1qN$!#u z9)mleTHi5#CdLeb+`fB9G~)yG%vD>Fpgrl$*u8B^Q&%|~mKN>=?$pK&>eqvQ8w-_5 zkY(L?b&&IL^`&w7*BIqpxPp0ohzrDtyQ=6+UYDc@4r|-B2p*jV*Bu6BhMGQs8z%!> zC1S2m*A&WuAe6U}RnPR!RAlk#qjI?ghUxe%tga;7K;TR; zm{>Qhg3-E;-+wfC8@MWCt&QrM!=wbH=1luewB+3ZmK9}d(e81=5OPtJEzrDbPM8Mo z1$l3~J|{s&1YxRH@lv73TbLOl-U}zidb1yq-%GjZM2<|JUUSBMWxDhYF_Ie$Q{gfdlEHZ`H00K#77}y3)>2|D4BF zLfjOO=RWuRg9O|~@mE*nsYBxgB@LAp+J^DYo$uE!{^beamnp0TD@S4>!2meR(1;@W zmDB1S5r+*@!w7^?Z`+f98t7}Jlp$7L79k_zkK&mjUfTXghBfBqLI)vj_GPtuDG?8H z^U;d2$Bk=`9c4tCG%6~<%+9m->*JCrL!|3r8?#yd*|gJKJDJxa^In8760_gruz?jK zG+uN+Mssi0^%9SB^*fi(L^{+^`727q+ndPPAnFzlr}6uN&tCp(5bjvERA%MO^}UVF zEMbIq$jbsI5#c~~eI8WmL_5ska}f{-yCcwk0*2YoY}Eutc$1kpIkTGcW9~@(&@=jdDKWa&%VrA(dFPX#-|t&5 zi2G!i$1QdlB%ex&!@U$c&DR!EyLCWoYsIKz5-vBWt|;ip7k58l9K}=kWlq91h1>1% z@)3C+tJ#cJpC=JW0a?Y=Np$eaCC^LpnG#PE&J9ZDpEvF%%t7z~VG3PJ)!#aA0@=EO zkXgt|n9>F+F7Bn2hnM#Ac_2Z4=^~_hpQ!74mDPm^Ay;6uAjSRc5HJM=#_Z`09dawu z=`~3t-bfO-qT$hF@-?Ra$J3t)!V)xs!EO{dE4kz*uI$+jkIBrT%^odNx7=|j3a{)7 z&3)y=e6WgK@>BVPG>v`*i=*3%dJO`~V6@ss- zfLNLy*mv%3M+^2vr@S|q?nH3M3}7b&x5*sJwGJ>Ikcsz+5eAJuZr=hOzJKd0`XPDw z?hh!%t!9PnNZXGaDt^hVkHUYTUBWJ#$B{t4pBOjk@O*U(yX>L3z$d`62g?Nf3{&J% z8Gg#pDz0|=FK>({^Ek=~id=l}%V8u9atM7NSDyPe8`8EM31iBeLfHnzJ|Da-zyGlQ zt@<1;B#sZ=cjO}U4z^|2kdIZ+IeRHcGA=csbaWMw{DNfEA$uiv$B2)}2}u|80qL=v zL4lVD;$mtF3+4co6xo%+#-uX5}-R^&Bo57_DA&9>9 zW1StD1+iGLc@$p%B)0iR!5>#92sXqQdooja_HI@#0^F2w?i1qal|1IxfY1BVY#98RnVJm*NSL8YJ;Jji`dpm??+$9@x@0HhPYCA_4yWZ$mlOAypgCNtLIFtu zft%=_ZmlPTCt?k?7ex2s*!-m}D*IXH0#D=7oP-?2ryPX*cs#>xb{9@5VH}wDfQKVZ0Q+bP-RBJ3$)OW>MRJ0SOkI8o`Be8!B2~1s(@Ig$d4?** z=YRP&w|M)^$R3}30zf)}2m9{g1$5~5>o1uhQK@OTp{JaymNgSOQ35;*8E1TA zI;X`*^p}$%t54vTNEX{$#6|m-M0rsP>?7`E_&;{M*qWmhQfzyk<|i)u*t$hJ)IY&+ zr%iE`1XE!w^BZeU3zcQbl36Muu$(#dTpRYmq(*fM=(%iI29C49mCJvq?r753)2XLt zrr+QlF#lri0M%C0W*m_f67K+1dp0_Pw^j5+d6{Y-T8V6Dt8?a8fA_J-rm!V0!Ya_~ z5~^q07^nC5@BEYx?F(xtE5}XdD=)u)KcZ}(VxkkO(T23sl40qaZ3M;a1-T3!+;So; zYJgOfgtJj=z3UKL# zx>O?)DTJMu{IZDoVpWkr8hL(!;q-70&HKguQDVx+5wso00D(&kIvs41m&yqGag#pC z!;#+j;;7u$BO#BTR0i&SwDEY5rdBF^PzGEZti3?=pdSt#sBl!# zy?J_kjD9PT`4S9)t5d+GwlpIXO%9a@3EMvE63z$vC^9qt&SbwB!E`{3Eidpi$uxgY zJfYBDINg=oF51;d#+~V$0RUF>W8jzoDnJ!i`|1VPkFN>!p^~fh-jAx-;X|D!$_b72 z9r2YWgBwGHlHC)lEtNRGJUb#FrJZ|^H^kuwwI1QDEnjtT`HuLnfHBWkX}I+VcUJld zsZ&^v^WBATJB!8JZrXRxU;M8hnh(3Y{4giugeb#_{O#v$e>uo(9!uWlyoZ}iC*!vK zP(4#m&TxZBl_YdJl-bpCEx;ENaoaRR3P|@oB~Kh!r*9_A9bFX^7Vw9R4wqM16u~{C zPrgyH{SeJ-G!C0&-+Y@(sH~CJT)8B+NOcmaV_M{#)h>sV_Tg;#`8fkZ+QTF111LE* zGxHM`!(hIfuT-2NFP)Dk3KV}N?E8A0-z%$pAjX<7-M8nBF$x^`}9wV@llr|+kJ9TiU=3I$z%Yg4>DGx^xNcv#WuSF58FI0rIuXeYp%g1E5I|wGcIJs9y9n zXq@-BT$GDAw3`vx{z~(K5lZOLd9=!1k|c%Q{adzy{0B1KFqwGY<#Yy8DexNJ*t4`E z0%=G)Qdoa?_!>TRJk$z=$%VeOSzhUdlC%TWe~wU(o!G1cZ+o_ zZckamn&BnjGJ&6`ZYx-cP+8B(#~BW9Kg{<@Qw&5d>%gx598Re ztGq_J9hQbL2-u7*cyX8e?Ki8k=`pznr*0-zN(G9ecUS%P89VlMT2ISq$I|g{J%>7lhN!$M8C0Umj4rBBmD#+zyPVK(L^+JUke3Gxef`A@lk9apPGz~ zA&)ef9bmctxE@>K=`kZU)MKQC(+ajuW%+IcPQG+h*gh#oD58+eNH9WK>7Oon^CBYz z!k7uT=tpV{OuTilo!zk)%I!b*C@ruO*e#1s8auIMM$3BymajYmy4tQ@8m_Dl+?-zzC%;hb+GT(t_Q2T#fjmUxJz4t zmH9+AUzrKo_J?xasf(5s7ejcw*Fho_!L_w}!GiaD%OCvmITUG*{W#tjWx#~Vvdk_X zt0xnWj8$-w_K2v%+$J3J6o)$T%O2yOYqu#+z;K|DT2-4y5~!3hL)kFfAiAzcg}^Xx zy5kL2J;FN0@dn(LvC_SM5dE+>Lg!^U9@{NbZI60EcA`YD3>4O}>_*B@j!jYBu)i8< zX;aaIPhX-pa6bh4n7m>tD5A^!*=UXg`Go@yEU@h)fObcn+B4V1h>GkT_Tqw5G zQ`*sjY!g%D{H{TrDjKY=4<1wR_m;8iEzfWoTc2y5)7qd!ep2VR`+or9ijA|rMFJf~ z_vJaBkGI!E@R+NA5;m80&rla;Y?ulAdH!(VDtYD8;OI6^`N~J-da|L6sIkVXeW=KC zNwgMj8XC2~%ln)~CAK`3%grWMS6$k7!SbE7Ij_;;c@OzIbMj@nim4&ZT8@6at`wSx z{a?DR@B-nni+nFv`^vUxpIi!_!A!k;c}U3A;`Avr%x(%9TZM78$GP64eKvaK(g_i? znQ?-csRcSpMpWIJEr0uKfbXCs0DMGk?Y3M8>zEX`wE6N1lbif&<|hA?t{dqDYY*zF zluS<)3M-~o8{X$18h(N6)8ONSo$WX!;Br>inORqfbhZ}m@+n~)PYxW`b1$Q3!&g*> zZELoD+A?=$W1uJTXgaa2yT?4FOE2lNPwU0h(5BhleYIAHYBuW3OpOIRB-gGXKgjba zC3nd4vO=^T#zHbJ1X{S{eW2HNl%mB251c~xL*K1-F1I-#&M)F(#d(8969!~$nrS#B z$CGhF7vd+H(feaYOeb|qHg_%IMvQX~)+6G%f0n!tarkx~5#O(G`Msr;hGun%oj23W z+MMvoNN1B=sKP1xVClM=A;Ck{R|dba?z~Rg(mn#7yaiX#fJdb%miFl~n=FkoL2_tR zh8n#xLJG0;>z?4LtOm5$%zB^0;0fIw>r39-Lzn8>-@Bu{COm!De;=2?H)BN1{t}Ty zV$z3}BA+=P$Jw2fYRLFzYujBA~JwTm!ro{`_X3m;t#@19XdO_j9&0 zar)iA5(AL^70B4+zYDveZ2?Wa+=L4{A<(o9ec_;wcv?s=?1cVWS`^=z7V`ZJG#EyS zb_MLaAm@sH(EEI|6HVEIu{fo$3rG0rMc>r5ES-}V+Pk64pBt?CAHSH`!Qc12yXleY z+6T>M*(KX_T3l!RgLJ~;t=iR*4K}>aUTyzz7s3!j zCGi$Q^0mS}lwcwgEgNBt-!W!HQ-PgX*b}icgF6CuqY3QrXD72RutM5BNEfe6s$+XD zhKTu#VEINwV|kb!>okr;$wrRn)ZR}3?+h?RO;`Bm z&+9{c!1MF~Gf3wJ(HSZhTVa{;g23Q+f@YU-8Okyq25JdP4J+j|I!;{PC;g?bu}({Z zb~7>z1vF9PTV>%$0pN`RvOx)m83mRRY}oe{RF0F~aQBlnLCmZ+7k z^Fch}NVJ>mQ0*HWDEHPN=4I~(IaogGB73LfNtQV@lzY>g&aeZ;7hhaI2+qgSgZAPt zGotTNsz_T>0=97UPbuMdFM`Fm;u;jJ$PI-o0raS7@TiPQS6`l{DygZ=eD>dX#` zNS}$IC3trvWz%ELLOol5KbyL7A`oHwWSJA`*`aahynH(9F{zH#;&%m)@-mG?&Ps0~ zUHcwZ>6%O#d|u>oz*Z55GBKZ|KcMHD_&D9(nCA7fXnWe!b+;OUnf)$%XMFr?ui5P0 zg}eME&o4?)V6b9G(ZS-?Da8MIxQXr09sPc3A3VXR*-$%E8qld0m4?_}|Cs2!+Cke$ z6Mqnl*o-@%KW2Zr&~3L|0A_nx(RRX@I3H_h4VX#?VyQ_cwv6d%2n zg${6FtJ7&oBp?B5b*tcB99zf$VvY>88gP+BURjR0p&Sm)BSm#y2KI@Wg{&xE{>sX@ zhSRG!^H5TRo|2c*)1;fFtCr$%)>=DSk*+#SzGY`{o=@El|tJNmet*MNgPrC?FHqZE0+J19D5b}sQe;1vJC1sN$)XN|H;rm63 zTWFU)cxqoOB5om-hy-cEL_c)o3ZGEDX}kfvgNidMPh~UL<|TLX>3gTF7%zpcsE!86 zaXCJO#mAEm0H`>ZSP}t*MIxgC|6|?rK<&-_J>suiwg_Q8K8p_TUWub#uJ(U@@aWe= zTajfkHZ^D5%k5Gg_?!Xi_hO&E5T78z;OVQMk#Ap&t>skg%OdeEe`)ZS{I| z>$SU-#?v|edKG#9&HL3s`rU%c<2_8z>pZ*>!p@Q@3E1HSd)7YM>T1flNDUU!ipI>w z`gHyW;&9pWJnoCG&+vu%^ zhkA}s-9$l^Jvq@<`P;L}6#gf}7L`kV$f8NSuuBkWN6RPbf#8ODEdO++k z4W;1J)j-tmwiGt?=SFp;rU%DXZ3O^fr;oU_5r(&C#oJl+(wpRQ&M_BDgLv5+8_LZz zgaU31xzC8iiN{J9f1P8mC(Q=lc;?8mx}@IrekpANc7R2C1N;o99t{y32p|)k$=<4P z-eMX$4Mx^(=1)s=3Gd)`hVBq9!()}pd-bTc2?Tl?Gw1ehPkBkTf3L;{Liy*YBMdqvtScULUMDb(E!HXgM4>qrr4{zOxQ) z$t%Jwo_FT;H3Jr*e5nPQ;n8cP!~FH|t5^gQCo9zaRNSug&F@ji21KLD%|JiqVhL_3 z=K9mEA)-yE;x})f-7O$@DV^G}wR7-LE$7#_@7r#Kxn%SCu_KrtUW`2s9!jb#nt+aA zAPfb&_@ReJj!9-z1%9zLesS#Yo_nS~TzPR&4P2W2K&>%?ma4YNffZt&;s$s*rDt3fC)z)O?lQOWnAHPN|e6PyF(PQ02MTgMYlfebXUh zE&zawroc>sgYYl~`Vaz1YP)yG&}kJx%SWuaDxqd~p%Lmro5rg2(-2|UA?Ke#2|?PQ zOIL&sH(g&V*zO*0tI9bEYUvgHPc(Zvc!tX5D(K0BtxX}PqZMczTpdO-l$cMqCwyoI z2<|<=G1_BXZZXY|&HO}E9otAh9v@V#SQ%?zbD!Q@?Wcv6pJm)BIOJ1&21|uu|p7au=>gG*U%0p4m>@% zk{KfniAc;iWW=N(Mq6so;BEj^>TF^v6I-c>$E`Fd4hCCJVH(I}KO=TH{GYHI$tG!W zF1adZvTvZ7SXP5)HS)-a*-~V7ID;v_IOX5Gs>!A&VM-5JZw2&t-PgXQ z3M6HcyIivYj7`^bGca}WcbvVX=zQ&x(O#&Ua)`s$JYsj4`qOFmwRVJxBqV|W8SCxQ zfOw}0+HMCnt6@I*C&7#K)`*5-jq8maw`KCl=5`(}53;@hJSbU3iUktjj0>NUz~uV` zPRkf>cK9FhNG+jRPTZ!eE5v$omq%UZ`OUTpY4KqZe-vvrN7Vjk2*zVkxu?h!(>rq^ zr}`p_#ohkk*)u^tNE(ZOKO_zxGol_*cqdsHH!bfi7V$L6v#y$5xwD}LkFw(MW$PPt zV8U02Y^S&US;L9&%284})L@pRuc-m)arV|NSSu5eSGVaeM8Cjv@6b{gz|D- zmgSL|*T5z3{cx~bw8|pU9}EHlQ4H zDRPwbE=19tWIXPTK_mB9U#Po?JLb(Rb)#kF`@-&Wx&+ZPXWB#B!J79@LDXfU#b=sxH3J?{Jd{O;rT z-}OhwaUJFD{eHd9^Z9%{q|P?o9vsFl z(}S~|w0vb;lI23~fTI>%V<`{Y9{K9I?g@v`~MDtXM^lWmK0~9jtQ&f^1Q=|H@k&*bBwgxdh{PKQ2Cwf z4N+E>`6K5M$zP-b+-F~wWD~^g7T2rV!0}T#>Ur+q$A{tsQAu$IY4wp_6CNdK zgU&IXUqTf>^xmk)87KnRj4sXTg`Tb@CSCcBfd4>HQ~6K{Ue8K@WgaKkd-;ix6c91t z^7k+Z-jr02hG05o#OACKaTg8>W!EMV1W9{Y$C~NX7N66f|Skm3k?fXk*Ga91P zjEJnEYwsk~|EjCDzx(<7nJ*!7V4k%Tk7oz%%O4*-syV?@pfy`CqJRNICN|#fs&Eea zp6w<^Kt@ia-rjTi@|T}=FE6}t6pDV@7eOPAp&!dkV{GR^;$;l8KeYc@?vy&Pe883u z=p#2FXb4sh&pLo1K)}=vGZ?-4{f*&%n${b25rD=yxPOIT7;(st7V@afhMMw1H*5;`Gf%D-G5P7v+qnO8as zL~bki+4NVnT8I$_i9NEksl^Iz^RM#K{Hh4AL_hSzbTG>#Re74ptys1Ubn=`@lN=@kG5F>G!#_0>Wi`iO+^lvq0msn9e&!eWXD3Av%0;3aN_dF0~(U?g>`WkaV z6gKrvz;I%zn#DX*o4LK_AS7b{f7BpKUkUsm)+fsR z1hF*>$E#BA?)v0gu^E-GXzfr+g}$Q!Z&|!&lA%7YgvCCtM|}0^=$-2a2WK88 zNtlk6?X()6;halA6p>a3OK#O*hmzj~tZ!{6KZvMwieqcZHI3z?bgegr9NQ`QYJfOXllnhMq5CAmDV8{w znf|aBlvB(_8%e2D?suMeNqTp3FnwRg^H4Wc=#oP@7V|?CqR{ zVjv4x%3YV{v<`e)&&E`%e`~^=j2c3-gDlO|;~qxOX^i)*z^kxD>rOTyKSXH7#+3uV z+g4bxE`baDcT$z-3)B+bk5lWG`JqSrhhCkd*T9=aK{;*QZ_=0;IqFx-5Lhf9oP= ze1hoozezFwL;D6t-M_y7pW9Zf?u%UaMcJO27H_=|^SJW<#I*epXG_ z-`=tDZ7pGkfNUAhrU6Z@Uf%rYr5b4yhktj%BU`wydvn-6)Z|%mAnq2MC7g&jy*)w8 z;cl3RBh62UcX2i9Uo)=Q>WxsB$^bc2B&oFSFNVqK&5aaMt8wff70$FqtGBbA*EHC@ zNV*ryIc1eURTDJ2G6@auqF3B!PF$V_wt;>%Xjd$cF80EX@8N~dR%5LFre#U@&4w1= zMq6PjwrBE)E_VHs_m@|;D1V%oK}a*ENSKr;&`Gz0WHRy9k%4~RxJfj$ko6Z?40B2R zrNo08s8*1kGln< zv@6~JK9Bz1W#hRX`R_#xwmqyn4}T`0(&q!!(TCx4J~{KvHb$hHMC-$%l+o4VLp7IX zwhZ0aw`~8jvBwUFi8?ovDZdC`Ap}&qVWgHpIKC)8K|RKv(J$cYm1^E1+NcGAw_1s^ zFbr4u3X?K;Lvi<;05Btrka+(ma7h|8(q_WOC_d73RQL$Mm7LGqjJd6vH(JR)9TbvJ zvF|;r8NYe#M#H+k=P6M_slAUCw}oac+?5e8vTk?uqa~J$r;6;z%djXL2%xXj=dohqJyLzT-4!yc2nrtI>eJ2Pj^PII8rF2CD#~$v^uq%3Eo0I{kl? z1j!rE!zhmoe?OPQ8NyLbbtReBQKRU+r`mtD|600vVz_Q;WaaPose(NFmqRbcs(D>z zM{e+b`#JKUSqe?V9(;SaSwUsT6vhDSt9f9QeaKF>Ac_6&N46dEsq)}zh)3N6d+L`L zhqWIyZJ~fo#C2C+bo_=Sc-$|{NcEWUR0?+sTjTndo9s)$R4d0`h&Z>t1N%FI@1e_b zne+ZT)sGcod8Icwhq?wiWWwG~U&zJm0LbuK;}DG3MbX4C`C?(ly#V=)7>Qd)&kE^@ z6Oy8@@Fcw0-ijzBQP?1K>|TJMWvq?Oj}xLC7mmPj#kH-;$QE`0eJKQZM;#>Qi`2xTI4fiSIwS5G8tD8}+>$jnc~%6`bRMBDV_|AM1K88<(aB zxPAodpW2KOMQ$Ti;RcHA^t*EN!1$7KPJ%k8l(fu`0Wr$LU;YD*#pcS!;zm6WEK1Z+ z9$9{~5`<rH9LhRyme{a9qVYxwJylYLq$pV6N}l zyFWoVk|@56)N*mPV-)>UD2_AuM59b48Ju*rm6Kln=Y7062`zolTQ&7bLv{bNWc6<-1)To+Qp_$EoL&nTcY zvyEkIf}U)=%Pu1svhSE;3QmoPH&-rwtYpPYxv9KOCC+H48rBtsRQ{^%T}D$RrvMlmE%@FLG@^}sciYC1i@5}ramZl^JVw?WaEX` z0Q*!mh3A~{Qv20;@Z~Q1XA+>?Hcs77qe)*U$)k0Hyt5A}rdcpdZ$A`cXhL4##3-}y z=W;6;?XN8~w4-RTT&&4|F?sG+jIwk-h`zM3l|C zCNv(HJ!-MZwM}0oHmQz%HD8R^`1OI9-THm5KYuoRCT_l?b#|02L@*o`#%1Fd4}>KI z3)QtEy3NH2JMo%q`~)1%EDR<9j82oiB@0vf$IqXxI$t`Kg%{{ymwt?b4Mmq7rdmL} z)l#iEI@0miWka*{%(jep-_%#Vna`U#(jxD+g8s^Bl=*NOT5a;&FzJ+zf%XU`1Z;Qu zg3vcU^-Q6M^RvwPmiKuD>%6dzxJ+`-%zWU_cVb)klugUkd9!9!hE0&3 z_t2r$v7Po!$@5Hs^XO#M{Q)+tu08=_S#_QT!+?NRz|>vt+>2^OoNkiwsm8!_s zbvNiM5X<;S(qxCIMU>@9G%d2S8)Cn*a0C9IJ5?w0^cmnuLuB<+&rOg@@^vBz--4jT z2G{FC8_c5fh&sOZ3IG)_ZM{8yZ??5(aT&=wANlOkl4w==N+xNqPvfu$*Nu!cnU^Ry z#Vq_uEUQM{%4Tzk$!XQLfv5A#6PN%gS2>u*WB~dO)21?L%qzIEaCJ+K$}0nNEGyAo zgo|_z8!tu`?0W`PKwI+@6Qg6h^~%tpp2u&NjYcq~RRWx(ha^Tm5xwBiaK|2xHy*;?b$k94ct$j_g3B^wX3Sm;o$$&2jm^riN(ec7px%RCQg%Cy&tr?_)$lZdxHJ1PO$q8ae|EN4J3=YZ~~MY6YN7G z(;1}x!1=#VZdH`hNEW{? z*Rrf8c$oK(rwQ4e8y0VDMT7Va?aI|;A4n$ExwauPtcnuPidBFX(;ELp$i5jOr#KW7 zBmZ;x&a$FBZ6EI~$(|V$MK&Lma$lj-lbMrm`XlO-=Ur9WXp{lIZ*Bh|lTp#hNPN?@ z!=014Mv5^eATz8h`++>JMo$)6==DVlz=RYYFsCn7Nm z>>?H2Q61RaUe~Xmzl2L?u-@Y4IV&b3{PUi}~^>xtAow^!n8 zYN?lv|KpmS*>a~~aW+1VH~jn|W?-@mz>qx~G5O_vR#+&ORW%}_6Z-!49OW2+QOOF( zx@-vFN$xq&3dUS%j(DMeapXLAP1k7M1weWX_i^yG;R0#X#Gb%aT7JwV&vB)-2CqwY zw>CxFQsm`Zl59qq)vjM&sSG#*49#kc3BBJ#8=`U^pKz*1(MjUuTY zP448xwk+r*p+v2V4wxZLlqHqk^~`a(^_CNSC-*-9B{G=exmef};b z-Evhc#QY?9w>g$mlklZeToL!y1?Gxcp@`p`u7eiiCVLMUlz#Cf8FE=~)O4^)cUzka zj@INvu2y#d0KV_v-=i(LZ<6if3KCoeMR<)@g1mucX!Klc<3cmn74~1KRG6TB-6oal z$p3oZS^SPG5x;*6D4Jp`B$bGtjB-f*Dt~-msnD0U*D8Kns*bBZIJtm7Sl$ayIM25l zT-|Y{h6`ZG)4A5fuXR+l#12vZ>G|I%E6n-}p_0h+GWz|vQsSk*bIUQ0R$lJd^nOz} zkLuR@JnAy9`z?0c6lKNT+UQ5}tEk;2$65b5@+gxKGH0_jk1vz3yVrfCRP(OXoPU~| zkoNCtc9zG#Mk`gAPKLu6F3gfKkobx3xFEbR;D?onLxPjB1YeCv3Cf6irZ@1I06}o8 z1ru@ObnOZw;b6~z(*%r_Y2RU6NrGw@?sZPh=(xIdU?I#b{M(dlEd_@fPC`rT| zhxZrPo;A*qIv8(mueF3CpEmJQW<>NqMUoq30HWX{K%kS2K3}A}1Hbw4T_IGU8t9X%4?^OL0P2L+e57=)d}#iyp-EMjZX~ z23KIx+Q?o&TuMgDcB6;QkQSJ2r8HB{_~-D-(MeBVk3LcB>e%A<=>p<{ndz1fJVTY~ z&^qfxnj+^g8lx-SGk<1rW!-`_==wD9g1BYet(W2JXX5UkFiezuxBS_j z-P<6xB>4ZRNZud_h)mSVxVxr@ArvqFd3S@f7F400#5nM%?OjyxRR!wjS>DO2!SRUT z*9#DzWsccSTcRRgscS#SGrmO4@z3s(rD>GiMBn+#-l6y9PXJG`@OesgfxdKF08fa& zl$N8yhpi@}c7pRw)R1AX$PM<+eF`fbg@ z?Vd`fw8%lAFo8>YWfG|+P?45lV=e3+_s5gn{^{pS$#_)f{;FFi&)MMi_nlgu<7pqBuBG*_i;w@ zBJ`c1G_u;-b9SDr$^wW>%4tlx&f1=pXp`Uwd*vG~&Y~*GulNNspWHx3W6rg*_T%MC z5;~Fj7{`f=$FZMR_R#T#SznGdJ>wh}uRZGd&wf2W5j6#2@ZwsuUtKS~F>Q6X@VO>z zM-DYEUVM`~^v6FveAO_@qu#kj1^O7_;1U)B=p+_A@k|E)1Cnz2z@qq`V`3EIOeJZG z7Fa7wW`s<^w1e)0-}vPBhA9+n2h-qPjV^&6&8FO67MIJ78#v75kl=K+dq&-vi_wSV zgX;n{MMgLCF~!ZrE$vVqXhGR*NtW*~Y=GW=TC@Hrdih=uUv&^)nuX5|7z3e|nxBw5 z`KC_o!h6$%|DM*XJFDY(i<1FONKys|(Qdh0C-ERrjizzUbe9kFm09EtP82W>mr zxAT*;DV7vXbhBOA&ehXvygs*%&YC%9ev+W@`hy_&N}}jqlLAIZ*IUyG z{jOaMyD64={ng0T9R%>SFb3pw6W2_MGb!e#57hVXX`2j7SX%(k_U$BwI=7#Y01hw3 z9Tb#OnRV0t+g?DVnPRE9V7;CrRdT1WOP{&%=d0jg&p*Q{Ra59e@pV%1g_rvW(;_Q@ zqi@YB&&x8!rt3sC417)rcjYGczn0ld-!zd@!KBM;eV}+IlH^x1^KEEpcx>2tWn|~- zil5%>7|Rbc;t??YPjc(FBr%cmQ~lJ&`^9Mf^uURLiMpzy*-t%3y~&Kh3qBw67a!=E zjS7>II9+IJnPc1X2=_Tgytd}gh%2qk5FwCn2i40j+E_d*@s~fk*y;o*NKpA&==P0+ z1l?S>VE(~i9&!6`pDX=wbhAeit%!0Zd5i4ANRgPUHIdzmk5hW#&)sJk8)0*!wDvyQ zX%ezW6W6a=;NJK1<$!-vHe{@sW`-W790h>c>-0?+Vx8~I<2v|6^x;jEaWLy9BgkCQ zzJ<8r-flN}T_>gBXKHAk^dneXsj${?FTz)?4$S>l)L8;%(W~=q>+S82cSXH$>m6lg z;@c%!$W>mLJ)Fat;g!CtDZ&rdf3jenQ|JZ%GnhXTFnvyhlN#vm%QXkL8N+2gL2}vN zl%e{eIeE*)%@c=TQ1e_9*B|&)a_P|jt@pFS6g>IA*-<|s#F00C8MZIWM`lknu$_G* zmxgryM7>bbEk56qmAU&~h8ptkF=t2*b#-(9aU^env0 zpXUyTrPZdi`hwtIPA;sWem!~ly1}7MEa{+gJQkA)N84M*&Z2kRJP*!_RyR!k!2FUH zDTCJr7SO}321MOE>FCgqX17h+7*W>M0*8Mg7|`LJ7v0&zmR<>pG1mz;7)e-v_FBra zIk5g0H{Ug5C#-$oOo3N{K3H4fOL}78vf)r8((!%ycRMsxlYL}vN}TOe%IjG0DuAMcFmXD^DWkO~Vu-kz0f;dEH!@`tS|4v# zid?;*Q`qw8$(L6hPc1N_XI77Om8k+%*Oa^MOL!qBbPQ8ua%cq|w5E zCn8Gx<9*^2GSH#&G?;WrieFEFji%#{0o}>g1w;bEBMW9i;bQ%oWJ_%;%a4X1QXBYs`I~2^6r!j}cP{ zOBzW`@|4%4`yNxh3THHLwSx5)hE$S#&57;~31doV)3>Nz(z31pMZJfYG^>`LbqQtQ zvV-+Z8ST63kOa8McXc2wv}AeX5Z2{Lt@WEjyuZ(#=j5JlAE)B$OXh|(SJNr+ss;xG zly0MPMI^_w=O?Gv)Etkw`4=)x2`CnLb$C(IgbL__${;cA$2Utgs)|^R!%aJDBhfrBo&W4@%>ST!6P7oPs#iVY}(A|iD)q=gq^vrN*(SSXS zZg|h_t|}bX!SXIn@bt-QhY7qO;4zXIn!4(7FYMwvUi2wJs$N!IL_y&T|Of#~m zoH^UpQ+hTpA;lQud+6fT@9!V$Ik=7^j1boNnpFADG2L0{bW3iFxqNA8Ki}llrsa+A z%im-kxd=TIm{hR8|HS@Lj|Y>p5VxEhRGA+5htkf+d|K=*rQkVF=2zO9=6<%+KP@5K z62lsX$&>{DKYQN?F=+ayVPs&Sb#7JKOV_}VJEo0Fv%VxpeXQ4GX{QaaT}RBM#7xUk z$YP1bRTY#rhBtW)sv;B$N+tSQYffQoqi`6D~PJpcqf z7+*&YvNLt?^=4fJSEAn`uIJ`Q8lj-;B-H4~c~{)qh-O%_LuDm-x< z-BqN^t8rbg*_x)GbOd@k<~=X<7j%~6IYyGkz*L3BczX_GD1Bfc2v$X#KU!)@OouLv z3Cl;&CBHR=>h1d$g`8PHw{~})Z6!L)m}!T73F5;y`Wxm>5cLW8+;~VI#)%_i<}%ns z*hy?pHofx?e%~n4I8e&BE=fd!B!_ZK11vHvv9($3FuzH8k)0AGo8Dk*EK|-<9jaftLWHB@s z69Td%jBrYc9P$2k8*N7z)pbSvXdEX$o<-a`NoxqIJG8IMO=Dv-itjFP$2sBvHNyk^ z>|Y*H7)-JdMy1o+L*#N%!g;fG2$_UigmP>ZGwN*4UJH!Yb(w zNOVNu%oLb>lhKP9pg3_WU_ckvas;wg?4|Pq83dmPK6f1<{A0PxP1M-%3q5sWP{whu zSf{l~Sp}6)%=eMyvdaqFHqgP!p`Gm%X3&yOt^`Hq*YNWy!bR?Qng(!UvhY0Co&YM66P-z(jgCDetsEJ>_X4J@EQuT6ooN9~DGG8DHXE2|;SAQWwE_)t#aQb%yKw!!u<1dY7VjQ;*Z`@B(_ABv3-A)p-(T3E$8XfaO zfZ|&>s04ljoE9oI*+vsyRqG>HYN->zACVv!&riM&lr{#k4&y8D-V?bpvzV1C!^HHI zf}lS}ZbZ9(gPtRZ|ckpCgu!wLw_>i>I14>Fg& z|B|^Z4HsBiRQf#*{k;|+#g|5yEsc$L?>~S^Rr}s1`BNrG+!FE9V5E9s)qDHCfTp|? zFWIrRzRqJg{`n!D&bxHjtA4n{a+3m+0{*r-rG;rBP{SCR)7#jUe_@$7%Um=!kkP}| zxb$i`x#|14oo#WF*#~)E>ML*0>kk(3QINj6e|shh7?Ql@w4gcnEy>A|cLfkXrc&pb z(sO53}o~rH5T*G3{t%fPp@+C=Q1jwAqaEd&F9^JRH!sWbC!ld!W$Ib0gK&7$z=( zVs}r&b5iPShS>v=6l6CX;pKarKv)E&BOuEn=hn{wV;+!4WaN2)_ox)(onfgSj=5_O z_oT-1RXf~Wb&VP}n^@9cD6)FWQA0!wS|7)E^P!K72_GZt}@5dd;@`6TSqyz zV`^U>A7>Z7GvZSwIAQg7V`b9Ei z6uvf@$++Uo5qM#QDtanIw35G(vU|QTNSQ(va=-0&pf-5uqU#hh5iBR>rhV`>G<}ij zVUv|K-%3o4JP)x4RyiF`s^XUNxqNmfD~9}bDRai1SJb

I-YdEym)ph4O7!WrmRk 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 z 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

i@qByauNJ$ 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%0Dl1hA#M+J1 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 <7)msu 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

dhDKxJ4vC3w8w9R#Q##WZ)~wo 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%0DI9J?C|jPRz_6h%jG_+9aV`CnlC_5#tLs9) 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 S(Eow|eY=rpc Date: Tue, 25 Apr 2017 18:09:40 -0400 Subject: [PATCH 07/20] perty mandelbulbs --- src/glsl/rayMarch-frag.glsl | 99 ++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 18 deletions(-) diff --git a/src/glsl/rayMarch-frag.glsl b/src/glsl/rayMarch-frag.glsl index 271f45af..b7efd0b8 100644 --- a/src/glsl/rayMarch-frag.glsl +++ b/src/glsl/rayMarch-frag.glsl @@ -1,6 +1,6 @@ #define MAX_GEOMETRY_COUNT 100 -#define SPHERE_TRACING true +#define SPHERE_TRACING false #define T_MAX 40.0 /* This is how I'm packing the data @@ -27,6 +27,12 @@ float SDF_Sphere( vec3 pos, float radius ) { return length(pos) - radius; } +//diagonal is the vector from the center of the box to the first quadrant corner +float boxSDF(vec3 point, vec3 diagonal) { + vec3 d = abs(point) - diagonal; + return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); +} + float SDF_Mandlebulb( vec3 p , float manPower) { vec3 w = p; @@ -139,26 +145,81 @@ float sceneMap2( vec3 pos ){ vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat); vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat); vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat); - float man1 = SDF_Mandlebulb(newPos1, 10.0); - float man2 = SDF_Mandlebulb(newPos2, 16.0); - float man3 = SDF_Mandlebulb(newPos3, 16.0); - float man4 = SDF_Mandlebulb(newPos4, 16.0); - float man5 = SDF_Mandlebulb(newPos5, 16.0); - float man6 = SDF_Mandlebulb(newPos6, 24.0); - float man7 = SDF_Mandlebulb(newPos7, 24.0); - float man8 = SDF_Mandlebulb(newPos8, 24.0); - float man9 = SDF_Mandlebulb(newPos9, 24.0); - //return un(man1, un(man2, un(man3, un(man4, man5)))); - return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9)))))))); + + float dist1; + float bb1 = boxSDF(newPos1, vec3(1.1,1.1,1.1)); + if(bb1 < .015) + { + dist1 = SDF_Mandlebulb(newPos1, 10.0); + } + else + { + dist1 = bb1; + } + + float dist2; + float bb2 = boxSDF(newPos2, vec3(1.2,1.2,1.2)); + if(bb2 < .015) + { + dist2 = SDF_Mandlebulb(newPos2, 16.0); + } + else + { + dist2 = bb2; + } + + float dist3; + float bb3 = boxSDF(newPos3, vec3(1.2,1.2,1.2)); + if(bb3 < .015) + { + dist3 = SDF_Mandlebulb(newPos3, 16.0); + } + else + { + dist3 = bb3; + } + + float dist4; + float bb4 = boxSDF(newPos4, vec3(1.2,1.2,1.2)); + if(bb4 < .015) + { + dist4 = SDF_Mandlebulb(newPos4, 16.0); + } + else + { + dist4 = bb4; + } + + float dist5; + float bb5 = boxSDF(newPos5, vec3(1.2,1.2,1.2)); + if(bb5 < .015) + { + dist5 = SDF_Mandlebulb(newPos5, 16.0); + } + else + { + dist5 = bb5; + } + + //float man2 = SDF_Mandlebulb(newPos2, 16.0); + //float man3 = SDF_Mandlebulb(newPos3, 16.0); + //float man4 = SDF_Mandlebulb(newPos4, 16.0); + //float man5 = SDF_Mandlebulb(newPos5, 16.0); + //float man6 = SDF_Mandlebulb(newPos6, 24.0); + //float man7 = SDF_Mandlebulb(newPos7, 24.0); + //float man8 = SDF_Mandlebulb(newPos8, 24.0); + //float man9 = SDF_Mandlebulb(newPos9, 24.0); + return un(dist1, un(dist2, un(dist3, un(dist4, dist5)))); + //return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9)))))))); } // Compute the normal of an implicit surface using the gradient method vec3 computeNormal( vec3 pos ) { vec2 point = vec2(0.0001, 0.0); vec3 normal = normalize( - vec3(sceneMap(pos + point.xyy) - sceneMap(pos - point.xyy), - sceneMap(pos + point.yxy) - sceneMap(pos - point.yxy), - sceneMap(pos + point.yyx) - sceneMap(pos - point.yyx))); + vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy), + sceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy), + sceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx))); return normal; } @@ -196,10 +257,11 @@ void main() { gl_FragCoord.y / u_resolution.y) - 1.0; vec3 cameraPos = vec3(.000001, -10.0, .000001); + //vec3 cameraPos = vec3(1, 0, 1); // Circle the origin (0, 0, 0) -// cameraPos.x = sin(u_time) * 10.0; -// cameraPos.z = cos(u_time) * 10.0; + //cameraPos.x = sin(u_time) * 10.0; + //cameraPos.z = cos(u_time) * 10.0; float len = 15.0; // assume the reference point is at 0, 0, 0 @@ -234,8 +296,9 @@ void main() { // Apply lambertian shading - for now gl_FragColor = vec4( baseMaterial * sun * vec3(sunDot), 1 ); + //gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1); } else { // Background color - gl_FragColor = vec4(f_uv, 0, 1); + gl_FragColor = vec4(0.5, 0.5, 0.5, 1); } } From fe981f9ef1758588594655c0783bf45a279921a1 Mon Sep 17 00:00:00 2001 From: Joe Klinger Date: Tue, 25 Apr 2017 22:32:01 -0400 Subject: [PATCH 08/20] AO, ayo. --- src/glsl/rayMarch-frag.glsl | 64 ++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/src/glsl/rayMarch-frag.glsl b/src/glsl/rayMarch-frag.glsl index b7efd0b8..ed93e4a1 100644 --- a/src/glsl/rayMarch-frag.glsl +++ b/src/glsl/rayMarch-frag.glsl @@ -1,6 +1,6 @@ #define MAX_GEOMETRY_COUNT 100 -#define SPHERE_TRACING false +#define SPHERE_TRACING true #define T_MAX 40.0 /* This is how I'm packing the data @@ -136,7 +136,7 @@ float sceneMap2( vec3 pos ){ mat4 eastMat = mat4(1.0); eastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime - vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat); + vec3 newPos1 = pos; //transform(pos + vec3(0, 1.5, 0), cwMat); vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat); vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat); vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat); @@ -147,6 +147,8 @@ float sceneMap2( vec3 pos ){ vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat); float dist1; + // dist1 = SDF_Mandlebulb(newPos1, 12.0); + float bb1 = boxSDF(newPos1, vec3(1.1,1.1,1.1)); if(bb1 < .015) { @@ -156,7 +158,7 @@ float sceneMap2( vec3 pos ){ { dist1 = bb1; } - +/* float dist2; float bb2 = boxSDF(newPos2, vec3(1.2,1.2,1.2)); if(bb2 < .015) @@ -200,7 +202,7 @@ float sceneMap2( vec3 pos ){ { dist5 = bb5; } - + */ //float man2 = SDF_Mandlebulb(newPos2, 16.0); //float man3 = SDF_Mandlebulb(newPos3, 16.0); //float man4 = SDF_Mandlebulb(newPos4, 16.0); @@ -209,7 +211,8 @@ float sceneMap2( vec3 pos ){ //float man7 = SDF_Mandlebulb(newPos7, 24.0); //float man8 = SDF_Mandlebulb(newPos8, 24.0); //float man9 = SDF_Mandlebulb(newPos9, 24.0); - return un(dist1, un(dist2, un(dist3, un(dist4, dist5)))); + // return un(dist1, un(dist2, un(dist3, un(dist4, dist5)))); + return dist1; //return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9)))))))); } @@ -244,7 +247,27 @@ vec2 raymarchScene( vec3 origin, vec3 direction ) { } +float SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) { + float dot = dot(normalize(toCam + toLight), normal); + return max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0); +} +// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf +float ComputeAO( vec3 pos, vec3 normal ) { + float tStep = 0.0025; + float t = 0.0; + float ao = 1.0; + float diff = 0.0; + float k = 72.0; + for(int i = 0; i < 5; i++) { + vec3 sample = pos + t * normal; + float dist = sceneMap2( sample ); + diff += pow(0.5, float (i)) * (t - dist); + t += tStep; + } + ao -= clamp(k * diff, 0.0, 1.0); + return ao; +} @@ -256,14 +279,14 @@ void main() { vec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x, gl_FragCoord.y / u_resolution.y) - 1.0; - vec3 cameraPos = vec3(.000001, -10.0, .000001); + vec3 cameraPos = vec3(1, -4, 2); //vec3 cameraPos = vec3(1, 0, 1); // Circle the origin (0, 0, 0) - //cameraPos.x = sin(u_time) * 10.0; - //cameraPos.z = cos(u_time) * 10.0; + cameraPos.x = sin(u_time) * 10.0; + cameraPos.z = cos(u_time) * 10.0; - float len = 15.0; // assume the reference point is at 0, 0, 0 + float len = 10.0; // assume the reference point is at 0, 0, 0 // Compute camera's frame of reference @@ -292,10 +315,29 @@ void main() { vec3 baseMaterial = vec3(0.2); vec3 sun = vec3(0.5, 0.4, 0.3) * 12.0; vec3 sunPos = vec3(5.0, 5.0, 0.0); - float sunDot = clamp(dot( -normal, normalize(sunPos - isectPos) ), 0.0, 1.0); + + vec3 toSun = normalize(sunPos - isectPos); + + normal = -normal; + + // Visibility test + // vec2 shadowTest = raymarchScene( isectPos, toSun ); + // float vis = 1.0; + + // if(shadowTest.y > 0.0) { // something is blocking this point + // vis = 0.0; + // } + + + + // Phong-ish shading for now + float spec = SpecHighlight( -look, toSun, normal); + + float sunDot = clamp(dot( normal, toSun ), 0.0, 1.0); + float ao = ComputeAO(isectPos, normal); // Apply lambertian shading - for now - gl_FragColor = vec4( baseMaterial * sun * vec3(sunDot), 1 ); + gl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1); //gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1); } else { // Background color From e86f12496b008a6f1d142202e62869e439cb1e7b Mon Sep 17 00:00:00 2001 From: tabathah Date: Tue, 25 Apr 2017 22:58:17 -0400 Subject: [PATCH 09/20] new scene orientation, animated coloring --- src/glsl/rayMarch-frag.glsl | 153 ++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 51 deletions(-) diff --git a/src/glsl/rayMarch-frag.glsl b/src/glsl/rayMarch-frag.glsl index b7efd0b8..9206c339 100644 --- a/src/glsl/rayMarch-frag.glsl +++ b/src/glsl/rayMarch-frag.glsl @@ -1,7 +1,7 @@ #define MAX_GEOMETRY_COUNT 100 #define SPHERE_TRACING false -#define T_MAX 40.0 +#define T_MAX 20.0 /* This is how I'm packing the data struct geometry_t { @@ -19,6 +19,8 @@ uniform vec2 u_resolution; uniform float u_fovy; uniform float u_aspect; +vec4 resColor; + /***** Geometry SDF Functions http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm *****/ @@ -77,6 +79,7 @@ float SDF_Mandlebulb( vec3 p , float manPower) break; } trap.x = m; + resColor = trap; return 0.25*log(m)*sqrt(m)/dz; } @@ -121,6 +124,7 @@ float sceneMap( vec3 pos ) { } float sceneMap2( vec3 pos ){ + float angle = u_time/(2.0*3.1415); mat4 cwMat = mat4(1.0); //transform for moving clockwise cwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime @@ -136,21 +140,91 @@ float sceneMap2( vec3 pos ){ mat4 eastMat = mat4(1.0); eastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime - vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat); - vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat); - vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat); - vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat); - vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat); - vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat); - vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat); - vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat); - vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat); + // vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat); + // vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat); + // vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat); + // vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat); + // vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat); + // vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat); + // vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat); + // vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat); + // vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat); + + // float dist1; + // float bb1 = boxSDF(newPos1, vec3(1.5,1.5,1.5)); + // if(bb1 < .015) + // { + // float power = 10.0;//12.0 + abs(sin(u_time/4.0))*40.0; + // dist1 = SDF_Mandlebulb(newPos1, power); + // } + // else + // { + // dist1 = bb1; + // } + + // float dist2; + // float bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1)); + // if(bb2 < .015) + // { + // dist2 = SDF_Mandlebulb(newPos2, 16.0); + // } + // else + // { + // dist2 = bb2; + // } + + // float dist3; + // float bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1)); + // if(bb3 < .015) + // { + // dist3 = SDF_Mandlebulb(newPos3, 16.0); + // } + // else + // { + // dist3 = bb3; + // } + + // float dist4; + // float bb4 = boxSDF(newPos4, vec3(1.1,1.1,1.1)); + // if(bb4 < .015) + // { + // dist4 = SDF_Mandlebulb(newPos4, 16.0); + // } + // else + // { + // dist4 = bb4; + // } + + // float dist5; + // float bb5 = boxSDF(newPos5, vec3(1.1,1.1,1.1)); + // if(bb5 < .015) + // { + // dist5 = SDF_Mandlebulb(newPos5, 16.0); + // } + // else + // { + // dist5 = bb5; + // } + + //float man2 = SDF_Mandlebulb(newPos2, 16.0); + //float man3 = SDF_Mandlebulb(newPos3, 16.0); + //float man4 = SDF_Mandlebulb(newPos4, 16.0); + //float man5 = SDF_Mandlebulb(newPos5, 16.0); + //float man6 = SDF_Mandlebulb(newPos6, 24.0); + //float man7 = SDF_Mandlebulb(newPos7, 24.0); + //float man8 = SDF_Mandlebulb(newPos8, 24.0); + //float man9 = SDF_Mandlebulb(newPos9, 24.0); + //return un(dist1, un(dist2, un(dist3, un(dist4, dist5)))); + //return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9)))))))); + float dist1; + vec3 newPos1 = transform(transform(pos + vec3(cos((u_time+4.0)/8.0)*4.0, 0, sin(u_time/7.0)*3.5), cwMat), northMat); float bb1 = boxSDF(newPos1, vec3(1.1,1.1,1.1)); if(bb1 < .015) { - dist1 = SDF_Mandlebulb(newPos1, 10.0); + float power = 12.0; + dist1 = SDF_Mandlebulb(newPos1, power); } else { @@ -158,10 +232,13 @@ float sceneMap2( vec3 pos ){ } float dist2; - float bb2 = boxSDF(newPos2, vec3(1.2,1.2,1.2)); + vec3 newPos2 = transform(transform(pos + vec3(cos((u_time+50.0)/10.0)*2.0, 1, sin((u_time+30.0)/6.0)*2.5), ccwMat), eastMat); + float bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1)); if(bb2 < .015) { - dist2 = SDF_Mandlebulb(newPos2, 16.0); + + float power = 12.0; + dist2 = SDF_Mandlebulb(newPos2, power); } else { @@ -169,48 +246,21 @@ float sceneMap2( vec3 pos ){ } float dist3; - float bb3 = boxSDF(newPos3, vec3(1.2,1.2,1.2)); + vec3 newPos3 = transform(transform(pos + vec3(sin((u_time)/16.0)*3.0, -1, cos((u_time+75.0)/3.0)*2.0), cwMat), westMat); + float bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1)); if(bb3 < .015) { - dist3 = SDF_Mandlebulb(newPos3, 16.0); + + float power = 12.0; + dist3 = SDF_Mandlebulb(newPos3, power); } else { dist3 = bb3; } - float dist4; - float bb4 = boxSDF(newPos4, vec3(1.2,1.2,1.2)); - if(bb4 < .015) - { - dist4 = SDF_Mandlebulb(newPos4, 16.0); - } - else - { - dist4 = bb4; - } - - float dist5; - float bb5 = boxSDF(newPos5, vec3(1.2,1.2,1.2)); - if(bb5 < .015) - { - dist5 = SDF_Mandlebulb(newPos5, 16.0); - } - else - { - dist5 = bb5; - } + return un(dist1, un(dist2, dist3)); - //float man2 = SDF_Mandlebulb(newPos2, 16.0); - //float man3 = SDF_Mandlebulb(newPos3, 16.0); - //float man4 = SDF_Mandlebulb(newPos4, 16.0); - //float man5 = SDF_Mandlebulb(newPos5, 16.0); - //float man6 = SDF_Mandlebulb(newPos6, 24.0); - //float man7 = SDF_Mandlebulb(newPos7, 24.0); - //float man8 = SDF_Mandlebulb(newPos8, 24.0); - //float man9 = SDF_Mandlebulb(newPos9, 24.0); - return un(dist1, un(dist2, un(dist3, un(dist4, dist5)))); - //return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9)))))))); } // Compute the normal of an implicit surface using the gradient method @@ -256,12 +306,12 @@ void main() { vec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x, gl_FragCoord.y / u_resolution.y) - 1.0; - vec3 cameraPos = vec3(.000001, -10.0, .000001); + vec3 cameraPos = vec3(-3.5, 0, -3.5); //vec3 cameraPos = vec3(1, 0, 1); // Circle the origin (0, 0, 0) - //cameraPos.x = sin(u_time) * 10.0; - //cameraPos.z = cos(u_time) * 10.0; + // cameraPos.x = sin(u_time) * 0.001; + // cameraPos.z = cos(u_time) * 0.001; float len = 15.0; // assume the reference point is at 0, 0, 0 @@ -289,13 +339,14 @@ void main() { vec3 normal = computeNormal( isectPos ); // Lighting - vec3 baseMaterial = vec3(0.2); + vec3 baseMaterial = vec3(0.2, 0.1, 0.4); + vec3 trapColor = vec3(resColor.x+(sin((u_time+isectPos.x)/2.0)*0.2), resColor.y-(cos((u_time+isectPos.y)/8.0)*0.5), resColor.z+(cos((u_time-isectPos.z)/2.0)*0.8)); vec3 sun = vec3(0.5, 0.4, 0.3) * 12.0; vec3 sunPos = vec3(5.0, 5.0, 0.0); float sunDot = clamp(dot( -normal, normalize(sunPos - isectPos) ), 0.0, 1.0); // Apply lambertian shading - for now - gl_FragColor = vec4( baseMaterial * sun * vec3(sunDot), 1 ); + gl_FragColor = vec4( trapColor * sun * vec3(sunDot), 1 ); //gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1); } else { // Background color From 1dd2e9c7d820ecc965ec23645d13fe5e47896e31 Mon Sep 17 00:00:00 2001 From: tabathah Date: Tue, 25 Apr 2017 23:24:09 -0400 Subject: [PATCH 10/20] milestone 2 --- build/bundle.js | 2 +- build/bundle.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/bundle.js b/build/bundle.js index fa673a41..4371c5b5 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -48470,7 +48470,7 @@ /* 15 */ /***/ (function(module, exports) { - module.exports = "\r\n#define MAX_GEOMETRY_COUNT 100\r\n#define SPHERE_TRACING true\r\n#define T_MAX 40.0\r\n\r\n/* This is how I'm packing the data\r\nstruct geometry_t {\r\n vec3 position;\r\n float type;\r\n};\r\n*/\r\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\r\n// uniform int u_count;\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t *****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\nfloat SDF_Mandlebulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i=0; i<4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n\r\n return 0.25*log(m)*sqrt(m)/dz;\r\n}\r\n\r\n//Operators:\r\n\r\nfloat intersection(float d1, float d2)\r\n{\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 )\r\n{\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2)\r\n{\r\n return min(d1,d2);\r\n}\r\n\r\n//returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform(vec3 point, mat4 trans)\r\n{\r\n\t//columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\n// Return the distance of the closest object in the scene\r\nfloat sceneMap( vec3 pos ) {\r\n\treturn SDF_Sphere( pos, 1.0 );\r\n}\r\n\r\nfloat sceneMap2( vec3 pos ){\r\n\tfloat angle = u_time/(2.0*3.1415);\r\n\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\r\n\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\r\n\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\r\n\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\r\n\r\n\tmat4 northMat = mat4(1.0); \r\n\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\r\n\tmat4 southMat = mat4(1.0); \r\n\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\r\n\tmat4 westMat = mat4(1.0); \r\n\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\r\n\tmat4 eastMat = mat4(1.0); \r\n\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\r\n\r\n\tvec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\r\n\tvec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\r\n\tvec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\r\n\tvec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\r\n\tvec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\r\n\tvec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\r\n\tvec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\r\n\tvec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\r\n\tvec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\r\n\tfloat man1 = SDF_Mandlebulb(newPos1, 10.0);\r\n\tfloat man2 = SDF_Mandlebulb(newPos2, 16.0);\r\n\tfloat man3 = SDF_Mandlebulb(newPos3, 16.0);\r\n\tfloat man4 = SDF_Mandlebulb(newPos4, 16.0);\r\n\tfloat man5 = SDF_Mandlebulb(newPos5, 16.0);\r\n\tfloat man6 = SDF_Mandlebulb(newPos6, 24.0);\r\n\tfloat man7 = SDF_Mandlebulb(newPos7, 24.0);\r\n\tfloat man8 = SDF_Mandlebulb(newPos8, 24.0);\r\n\tfloat man9 = SDF_Mandlebulb(newPos9, 24.0);\r\n\t//return un(man1, un(man2, un(man3, un(man4, man5))));\r\n\treturn un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\nvec3 computeNormal( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap(pos + point.xyy) - sceneMap(pos - point.xyy),\r\n\t\t\t\t\tsceneMap(pos + point.yxy) - sceneMap(pos - point.yxy),\r\n\t\t\t\t\tsceneMap(pos + point.yyx) - sceneMap(pos - point.yyx)));\r\n\treturn normal;\r\n}\r\n\r\n// Check for intersection with the scene for increasing t-values\r\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\r\n\tfloat dist;\r\n\tfloat t = 0.01;\r\n\tfor(int i = 0; i < 500; i++) {\r\n\t\tfloat dist = sceneMap2(origin + t * direction);\r\n\t\tif(dist < 0.0001) {\r\n\t\t\treturn vec2(t, 1.0); // intersection\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn vec2(0.0, -1.0); // no intersection\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\nvoid main() {\r\n\t\r\n\t/** Raycasting **/\r\n\t\r\n\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\r\n\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\r\n\t\t\t\t\t\t\t\tgl_FragCoord.y / u_resolution.y) - 1.0;\r\n\r\n\tvec3 cameraPos = vec3(.000001, -10.0, .000001);\r\n\t\r\n\t// Circle the origin (0, 0, 0)\r\n//\tcameraPos.x = sin(u_time) * 10.0;\r\n//\tcameraPos.z = cos(u_time) * 10.0;\r\n\t\r\n\tfloat len = 15.0; // assume the reference point is at 0, 0, 0\r\n\t\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos);\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\r\n\t\r\n\t// Perform the raymarch\r\n\tvec3 direction = normalize(point_World - cameraPos);\r\n\tvec2 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\t/** Shading and lighting **/\r\n\t\r\n\tif(isect.y > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormal( isectPos );\r\n\t\t\r\n\t\t// Lighting\r\n\t\tvec3 baseMaterial = vec3(0.2);\r\n\t\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\r\n\t\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\r\n\t\tfloat sunDot = clamp(dot( -normal, normalize(sunPos - isectPos) ), 0.0, 1.0);\r\n\t\t\r\n\t\t// Apply lambertian shading - for now\r\n\t\tgl_FragColor = vec4( baseMaterial * sun * vec3(sunDot), 1 );\r\n\t} else {\r\n\t\t// Background color\r\n\t\tgl_FragColor = vec4(f_uv, 0, 1);\r\n\t}\r\n}\r\n" + module.exports = "\r\n#define MAX_GEOMETRY_COUNT 100\r\n#define SPHERE_TRACING true\r\n#define T_MAX 20.0\r\n\r\n/* This is how I'm packing the data\r\nstruct geometry_t {\r\n vec3 position;\r\n float type;\r\n};\r\n*/\r\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\r\n// uniform int u_count;\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\nvec4 resColor;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t *****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\n//diagonal is the vector from the center of the box to the first quadrant corner\r\nfloat boxSDF(vec3 point, vec3 diagonal) {\r\n\tvec3 d = abs(point) - diagonal;\r\n \treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\r\n}\r\n\r\nfloat SDF_Mandlebulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i=0; i<4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n resColor = trap;\r\n\r\n return 0.25*log(m)*sqrt(m)/dz;\r\n}\r\n\r\n//Operators:\r\n\r\nfloat intersection(float d1, float d2)\r\n{\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 )\r\n{\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2)\r\n{\r\n return min(d1,d2);\r\n}\r\n\r\n//returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform(vec3 point, mat4 trans)\r\n{\r\n\t//columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\n// Return the distance of the closest object in the scene\r\nfloat sceneMap( vec3 pos ) {\r\n\treturn SDF_Sphere( pos, 1.0 );\r\n}\r\n\r\nfloat sceneMap2( vec3 pos ){\r\n\r\n\tfloat angle = u_time/(2.0*3.1415);\r\n\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\r\n\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\r\n\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\r\n\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\r\n\r\n\tmat4 northMat = mat4(1.0); \r\n\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\r\n\tmat4 southMat = mat4(1.0); \r\n\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\r\n\tmat4 westMat = mat4(1.0); \r\n\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\r\n\tmat4 eastMat = mat4(1.0); \r\n\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\r\n\r\n\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\r\n\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\r\n\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\r\n\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\r\n\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\r\n\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\r\n\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\r\n\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\r\n\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\r\n\t\r\n\t// float dist1;\r\n\t// float bb1 = boxSDF(newPos1, vec3(1.5,1.5,1.5));\r\n\t// if(bb1 < .015)\r\n\t// {\r\n\t// \tfloat power = 10.0;//12.0 + abs(sin(u_time/4.0))*40.0;\r\n\t// \tdist1 = SDF_Mandlebulb(newPos1, power);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist1 = bb1;\r\n\t// }\r\n\r\n\t// float dist2;\r\n\t// float bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1));\r\n\t// if(bb2 < .015)\r\n\t// {\r\n\t// \tdist2 = SDF_Mandlebulb(newPos2, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist2 = bb2;\r\n\t// }\r\n\r\n\t// float dist3;\r\n\t// float bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t// if(bb3 < .015)\r\n\t// {\r\n\t// \tdist3 = SDF_Mandlebulb(newPos3, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist3 = bb3;\r\n\t// }\r\n\r\n\t// float dist4;\r\n\t// float bb4 = boxSDF(newPos4, vec3(1.1,1.1,1.1));\r\n\t// if(bb4 < .015)\r\n\t// {\r\n\t// \tdist4 = SDF_Mandlebulb(newPos4, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist4 = bb4;\r\n\t// }\r\n\r\n\t// float dist5;\r\n\t// float bb5 = boxSDF(newPos5, vec3(1.1,1.1,1.1));\r\n\t// if(bb5 < .015)\r\n\t// {\r\n\t// \tdist5 = SDF_Mandlebulb(newPos5, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist5 = bb5;\r\n\t// }\r\n\r\n\t//float man2 = SDF_Mandlebulb(newPos2, 16.0);\r\n\t//float man3 = SDF_Mandlebulb(newPos3, 16.0);\r\n\t//float man4 = SDF_Mandlebulb(newPos4, 16.0);\r\n\t//float man5 = SDF_Mandlebulb(newPos5, 16.0);\r\n\t//float man6 = SDF_Mandlebulb(newPos6, 24.0);\r\n\t//float man7 = SDF_Mandlebulb(newPos7, 24.0);\r\n\t//float man8 = SDF_Mandlebulb(newPos8, 24.0);\r\n\t//float man9 = SDF_Mandlebulb(newPos9, 24.0);\r\n\t\r\n\t//return un(dist1, un(dist2, un(dist3, un(dist4, dist5))));\r\n\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\r\n\r\n\tfloat dist1;\r\n\tvec3 newPos1 = transform(transform(pos + vec3(cos((u_time+4.0)/8.0)*4.0, 0, sin(u_time/7.0)*3.5), cwMat), northMat);\t\r\n\tfloat bb1 = boxSDF(newPos1, vec3(1.1,1.1,1.1));\r\n\tif(bb1 < .015)\r\n\t{\r\n\t\tfloat power = 12.0;\r\n\t\tdist1 = SDF_Mandlebulb(newPos1, power);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdist1 = bb1;\r\n\t}\r\n\r\n\tfloat dist2;\r\n\tvec3 newPos2 = transform(transform(pos + vec3(cos((u_time+50.0)/10.0)*2.0, 1, sin((u_time+30.0)/6.0)*2.5), ccwMat), eastMat);\r\n\tfloat bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1));\r\n\tif(bb2 < .015)\r\n\t{\r\n\t\t\r\n\t\tfloat power = 12.0;\r\n\t\tdist2 = SDF_Mandlebulb(newPos2, power);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdist2 = bb2;\r\n\t}\r\n\r\n\tfloat dist3;\r\n\tvec3 newPos3 = transform(transform(pos + vec3(sin((u_time)/16.0)*3.0, -1, cos((u_time+75.0)/3.0)*2.0), cwMat), westMat);\r\n\tfloat bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\tif(bb3 < .015)\r\n\t{\r\n\t\t\r\n\t\tfloat power = 12.0;\r\n\t\tdist3 = SDF_Mandlebulb(newPos3, power);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdist3 = bb3;\r\n\t}\r\n\r\n\treturn un(dist1, un(dist2, dist3));\r\n\r\n\t// float dist4;\r\n\t// float bb4 = boxSDF(newPos4, vec3(1.2,1.2,1.2));\r\n\t// if(bb4 < .015)\r\n\t// {\r\n\t// \tdist4 = SDF_Mandlebulb(newPos4, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist4 = bb4;\r\n\t// }\r\n\r\n\t// float dist5;\r\n\t// float bb5 = boxSDF(newPos5, vec3(1.2,1.2,1.2));\r\n\t// if(bb5 < .015)\r\n\t// {\r\n\t// \tdist5 = SDF_Mandlebulb(newPos5, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist5 = bb5;\r\n\t// }\r\n\t\r\n\t//float man2 = SDF_Mandlebulb(newPos2, 16.0);\r\n\t//float man3 = SDF_Mandlebulb(newPos3, 16.0);\r\n\t//float man4 = SDF_Mandlebulb(newPos4, 16.0);\r\n\t//float man5 = SDF_Mandlebulb(newPos5, 16.0);\r\n\t//float man6 = SDF_Mandlebulb(newPos6, 24.0);\r\n\t//float man7 = SDF_Mandlebulb(newPos7, 24.0);\r\n\t//float man8 = SDF_Mandlebulb(newPos8, 24.0);\r\n\t//float man9 = SDF_Mandlebulb(newPos9, 24.0);\r\n\t// return un(dist1, un(dist2, un(dist3, un(dist4, dist5))));\r\n\t\r\n\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\r\n\t//return dist1;\r\n\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\nvec3 computeNormal( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\r\n\t\t\t\t\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\r\n\t\t\t\t\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\r\n\treturn normal;\r\n}\r\n\r\n// Check for intersection with the scene for increasing t-values\r\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\r\n\tfloat dist;\r\n\tfloat t = 0.01;\r\n\tfor(int i = 0; i < 500; i++) {\r\n\t\tfloat dist = sceneMap2(origin + t * direction);\r\n\t\tif(dist < 0.0001) {\r\n\t\t\treturn vec2(t, 1.0); // intersection\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn vec2(0.0, -1.0); // no intersection\r\n}\r\n\r\n\r\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\r\n\tfloat dot = dot(normalize(toCam + toLight), normal);\r\n\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\r\n}\r\n\r\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\r\nfloat ComputeAO( vec3 pos, vec3 normal ) {\r\n\tfloat tStep = 0.0025;\r\n\tfloat t = 0.0;\r\n\tfloat ao = 1.0;\r\n\tfloat diff = 0.0;\r\n\tfloat k = 72.0;\r\n\tfor(int i = 0; i < 5; i++) {\r\n\t\tvec3 sample = pos + t * normal;\r\n\t\tfloat dist = sceneMap2( sample );\r\n\t\tdiff += pow(0.5, float (i)) * (t - dist);\r\n\t\tt += tStep;\r\n\t}\r\n\tao -= clamp(k * diff, 0.0, 1.0);\r\n\treturn ao;\r\n}\r\n\r\n\r\n\r\nvoid main() {\r\n\t\r\n\t/** Raycasting **/\r\n\t\r\n\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\r\n\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\r\n\t\t\t\t\t\t\t\tgl_FragCoord.y / u_resolution.y) - 1.0;\r\n\r\n\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\r\n\t//vec3 cameraPos = vec3(1, -4, 2);\r\n\t//vec3 cameraPos = vec3(1, 0, 1);\r\n\t\r\n\t// Circle the origin (0, 0, 0)\r\n\t// cameraPos.x = sin(u_time) * 10.0;\r\n\t// cameraPos.z = cos(u_time) * 10.0;\r\n\t\r\n\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\r\n\t\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos);\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\r\n\t\r\n\t// Perform the raymarch\r\n\tvec3 direction = normalize(point_World - cameraPos);\r\n\tvec2 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\t/** Shading and lighting **/\r\n\t\r\n\tif(isect.y > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormal( isectPos );\r\n\t\t\r\n\t\t// Lighting\r\n\t\tvec3 baseMaterial = vec3(0.2, 0.2, 0.2);\r\n\t\tvec3 trapColor = vec3(resColor.x+(sin((u_time+isectPos.x)/2.0)*0.2), resColor.y-(cos((u_time+isectPos.y)/8.0)*0.5), resColor.z+(cos((u_time-isectPos.z)/2.0)*0.8));\r\n\t\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\r\n\t\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\r\n\t\t\r\n\t\tvec3 toSun = normalize(sunPos - isectPos);\r\n\t\t\r\n\t\tnormal = -normal;\r\n\t\t\r\n\t\t// Visibility test\r\n\t\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\r\n\t\t// float vis = 1.0;\r\n\t\t\r\n\t\t// if(shadowTest.y > 0.0) { // something is blocking this point\r\n\t\t// \tvis = 0.0;\r\n\t\t// }\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t// Phong-ish shading for now\r\n\t\tfloat spec = SpecHighlight( -look, toSun, normal);\r\n\t\t\r\n\t\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\r\n\t\tfloat ao = ComputeAO(isectPos, normal);\r\n\t\t\r\n\t\t// Apply lambertian shading - for now\r\n\t\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\r\n\t\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\r\n\t} else {\r\n\t\t// Background color\r\n\t\tgl_FragColor = vec4(0.5, 0.5, 0.5, 1);\r\n\t}\r\n}\r\n" /***/ }), /* 16 */ diff --git a/build/bundle.js.map b/build/bundle.js.map index 4ee681d3..724b673f 100644 --- a/build/bundle.js.map +++ b/build/bundle.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap defbe2012c3b729c6c3e","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/rayMarch-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","aspect","updateProjectionMatrix","gui","GUI","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","buffer","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","composer","shaderPass","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","vertexShader","fragmentShader","renderToScreen","addPass","getElapsedTime"],"mappings":"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AEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa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A;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,QAAO;;AAEP,MAAK;AACL;AACA;;AAEA;;;AAGA,0BAAyB,oCAAoC;AAC7D;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;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CA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,YAAW;;AAEX,+DAA8D,uCAAuC;;AAErG;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;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E5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA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;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;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;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AAC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EpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA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AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,OAAO;;AAE1B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;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AAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;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EA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,8CAA6C,OAAO;;AAEpD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KA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CA;;AAEA;AACA;;AAEA,uBAAsB;AACtB,uBAAsB;;AAEtB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;AACA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AAC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AEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB;AACpB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,8BAA8B;;AAEjD;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;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EA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,oEAAmE;;AAEnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AA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EA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gBAAe,sBAAsB;;AAErC;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gB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EA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;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CA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap defbe2012c3b729c6c3e","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"

\\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
\\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
\\n \\n
\\n\\n
\",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nimport {PROXY_BUFFER_SIZE} from './proxy_geometry'\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n var composer = new EffectComposer(renderer);\r\n var shaderPass = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/rayMarch-frag.glsl')\r\n \r\n });\r\n shaderPass.renderToScreen = true;\r\n composer.addPass(shaderPass);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n composer.render();\r\n // console.log(composer);\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\n#define MAX_GEOMETRY_COUNT 100\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 40.0\\r\\n\\r\\n/* This is how I'm packing the data\\r\\nstruct geometry_t {\\r\\n vec3 position;\\r\\n float type;\\r\\n};\\r\\n*/\\r\\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\\r\\n// uniform int u_count;\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t *****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\nfloat SDF_Mandlebulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i=0; i<4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n\\r\\n return 0.25*log(m)*sqrt(m)/dz;\\r\\n}\\r\\n\\r\\n//Operators:\\r\\n\\r\\nfloat intersection(float d1, float d2)\\r\\n{\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 )\\r\\n{\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2)\\r\\n{\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n//returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform(vec3 point, mat4 trans)\\r\\n{\\r\\n\\t//columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\n// Return the distance of the closest object in the scene\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\treturn SDF_Sphere( pos, 1.0 );\\r\\n}\\r\\n\\r\\nfloat sceneMap2( vec3 pos ){\\r\\n\\tfloat angle = u_time/(2.0*3.1415);\\r\\n\\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\\r\\n\\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\\r\\n\\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\\r\\n\\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\\r\\n\\r\\n\\tmat4 northMat = mat4(1.0); \\r\\n\\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 southMat = mat4(1.0); \\r\\n\\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 westMat = mat4(1.0); \\r\\n\\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\\r\\n\\tmat4 eastMat = mat4(1.0); \\r\\n\\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\\r\\n\\r\\n\\tvec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\\r\\n\\tvec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\\r\\n\\tvec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\\r\\n\\tvec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\\r\\n\\tvec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\\r\\n\\tvec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\\r\\n\\tvec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\\r\\n\\tvec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\\r\\n\\tvec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\\r\\n\\tfloat man1 = SDF_Mandlebulb(newPos1, 10.0);\\r\\n\\tfloat man2 = SDF_Mandlebulb(newPos2, 16.0);\\r\\n\\tfloat man3 = SDF_Mandlebulb(newPos3, 16.0);\\r\\n\\tfloat man4 = SDF_Mandlebulb(newPos4, 16.0);\\r\\n\\tfloat man5 = SDF_Mandlebulb(newPos5, 16.0);\\r\\n\\tfloat man6 = SDF_Mandlebulb(newPos6, 24.0);\\r\\n\\tfloat man7 = SDF_Mandlebulb(newPos7, 24.0);\\r\\n\\tfloat man8 = SDF_Mandlebulb(newPos8, 24.0);\\r\\n\\tfloat man9 = SDF_Mandlebulb(newPos9, 24.0);\\r\\n\\t//return un(man1, un(man2, un(man3, un(man4, man5))));\\r\\n\\treturn un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\nvec3 computeNormal( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap(pos + point.xyy) - sceneMap(pos - point.xyy),\\r\\n\\t\\t\\t\\t\\tsceneMap(pos + point.yxy) - sceneMap(pos - point.yxy),\\r\\n\\t\\t\\t\\t\\tsceneMap(pos + point.yyx) - sceneMap(pos - point.yyx)));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Check for intersection with the scene for increasing t-values\\r\\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\tfloat dist;\\r\\n\\tfloat t = 0.01;\\r\\n\\tfor(int i = 0; i < 500; i++) {\\r\\n\\t\\tfloat dist = sceneMap2(origin + t * direction);\\r\\n\\t\\tif(dist < 0.0001) {\\r\\n\\t\\t\\treturn vec2(t, 1.0); // intersection\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn vec2(0.0, -1.0); // no intersection\\r\\n}\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n\\t\\r\\n\\t/** Raycasting **/\\r\\n\\t\\r\\n\\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\\r\\n\\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t\\t\\t\\tgl_FragCoord.y / u_resolution.y) - 1.0;\\r\\n\\r\\n\\tvec3 cameraPos = vec3(.000001, -10.0, .000001);\\r\\n\\t\\r\\n\\t// Circle the origin (0, 0, 0)\\r\\n//\\tcameraPos.x = sin(u_time) * 10.0;\\r\\n//\\tcameraPos.z = cos(u_time) * 10.0;\\r\\n\\t\\r\\n\\tfloat len = 15.0; // assume the reference point is at 0, 0, 0\\r\\n\\t\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos);\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\\r\\n\\t\\r\\n\\t// Perform the raymarch\\r\\n\\tvec3 direction = normalize(point_World - cameraPos);\\r\\n\\tvec2 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\t/** Shading and lighting **/\\r\\n\\t\\r\\n\\tif(isect.y > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormal( isectPos );\\r\\n\\t\\t\\r\\n\\t\\t// Lighting\\r\\n\\t\\tvec3 baseMaterial = vec3(0.2);\\r\\n\\t\\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\\r\\n\\t\\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\\r\\n\\t\\tfloat sunDot = clamp(dot( -normal, normalize(sunPos - isectPos) ), 0.0, 1.0);\\r\\n\\t\\t\\r\\n\\t\\t// Apply lambertian shading - for now\\r\\n\\t\\tgl_FragColor = vec4( baseMaterial * sun * vec3(sunDot), 1 );\\r\\n\\t} else {\\r\\n\\t\\t// Background color\\r\\n\\t\\tgl_FragColor = vec4(f_uv, 0, 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/rayMarch-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 17\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap 3aae6504ba570c47e9d2","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/rayMarch-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","aspect","updateProjectionMatrix","gui","GUI","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","buffer","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","composer","shaderPass","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","vertexShader","fragmentShader","renderToScreen","addPass","getElapsedTime"],"mappings":"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AEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa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A;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,QAAO;;AAEP,MAAK;AACL;AACA;;AAEA;;;AAGA,0BAAyB,oCAAoC;AAC7D;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;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CA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,YAAW;;AAEX,+DAA8D,uCAAuC;;AAErG;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;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E5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA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;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;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;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AAC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EpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA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AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,OAAO;;AAE1B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;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AAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;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EA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,8CAA6C,OAAO;;AAEpD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KA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CA;;AAEA;AACA;;AAEA,uBAAsB;AACtB,uBAAsB;;AAEtB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;AACA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AAC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AEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB;AACpB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,8BAA8B;;AAEjD;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;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EA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,oEAAmE;;AAEnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,+CAA8C;AAC9C;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,oCAAmC,QAAQ;;AAE3C;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,0BAAyB;;AAEzB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,kDAAiD,OAAO;;AAExD;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,gBAAe,QAAQ;;AAEvB;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,mBAAmB;;AAEtC;;AAEA;;AAEA;;AAEA;;AAEA,0BAAyB,qCAAqC;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;AACA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA,aAAY,OAAO;;AAEnB;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAGA,kDAAiD;AACjD;AACA;;AAEA;AACA;;AAEA,+FAA8F;AAC9F;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,6CAA4C,QAAQ;;AAEpD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;;AAEA;;AAEA;AACA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,6CAA4C,QAAQ;;AAEpD;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,qDAAoD,QAAQ;;AAE5D;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,qDAAoD,QAAQ;;AAE5D;;AAEA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,qBAAoB,sCAAsC;;AAE1D;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN,4BAA2B;;AAE3B;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,qBAAoB,sBAAsB;;AAE1C;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN,6BAA4B;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,+EAA8E,kCAAkC;;AAEhH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,+CAA8C,OAAO;;AAErD;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,kDAAiD;;AAEjD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAAQ;;AAER;;AAEA,OAAM;;AAEN,qDAAoD,OAAO;;AAE3D;AACA;;AAEA;;AAEA;;AAEA,kDAAiD;;AAEjD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAAQ;;AAER;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA,sBAAqB,oBAAoB;;AAEzC;;AAEA;;AAEA,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,4EAA2E,kCAAkC;;AAE7G;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN,iDAAgD,OAAO;;AAEvD;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,2CAA0C,OAAO;;AAEjD;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB;AAChB;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,iBAAgB;;AAEhB;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,kCAAiC;AACjC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kCAAiC,OAAO;;AAExC;;AAEA,iBAAgB,OAAO;;AAEvB;AACA;AACA,gCAA+B;;AAE/B;;AAEA;;AAEA,uBAAsB;;AAEtB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qCAAoC,QAAQ;;AAE5C;;AAEA;AACA;;AAEA,6CAA4C,OAAO;;AAEnD,mBAAkB,OAAO;;AAEzB;AACA;AACA,kCAAiC;;AAEjC;;AAEA;;AAEA,yBAAwB;;AAExB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,6CAA4C,OAAO;;AAEnD,kBAAiB,OAAO;;AAExB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,aAAa;;AAE3B;;AAEA,gBAAe,aAAa;;AAE5B;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,YAAY;;AAE1B,gBAAe,YAAY;;AAE3B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,oBAAmB,oBAAoB;;AAEvC;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,WAAW;;AAE1B;;AAEA;AACA;;AAEA;;AAEA,iBAAgB,WAAW;;AAE3B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,UAAU;;AAEzB,iBAAgB,0BAA0B;;AAE1C;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,yBAAyB;;AAE5C;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,yBAAyB;;AAE5C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,qBAAqB;;AAExC;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,2BAA0B,yBAAyB;;AAEnD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gBAAe,sBAAsB;;AAErC;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gB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EA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;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CA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 3aae6504ba570c47e9d2","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
\\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
\\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
\\n \\n
\\n\\n
\",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nimport {PROXY_BUFFER_SIZE} from './proxy_geometry'\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n var composer = new EffectComposer(renderer);\r\n var shaderPass = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/rayMarch-frag.glsl')\r\n \r\n });\r\n shaderPass.renderToScreen = true;\r\n composer.addPass(shaderPass);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n composer.render();\r\n // console.log(composer);\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\n#define MAX_GEOMETRY_COUNT 100\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 20.0\\r\\n\\r\\n/* This is how I'm packing the data\\r\\nstruct geometry_t {\\r\\n vec3 position;\\r\\n float type;\\r\\n};\\r\\n*/\\r\\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\\r\\n// uniform int u_count;\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\nvec4 resColor;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t *****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\n//diagonal is the vector from the center of the box to the first quadrant corner\\r\\nfloat boxSDF(vec3 point, vec3 diagonal) {\\r\\n\\tvec3 d = abs(point) - diagonal;\\r\\n \\treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\\r\\n}\\r\\n\\r\\nfloat SDF_Mandlebulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i=0; i<4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n resColor = trap;\\r\\n\\r\\n return 0.25*log(m)*sqrt(m)/dz;\\r\\n}\\r\\n\\r\\n//Operators:\\r\\n\\r\\nfloat intersection(float d1, float d2)\\r\\n{\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 )\\r\\n{\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2)\\r\\n{\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n//returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform(vec3 point, mat4 trans)\\r\\n{\\r\\n\\t//columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\n// Return the distance of the closest object in the scene\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\treturn SDF_Sphere( pos, 1.0 );\\r\\n}\\r\\n\\r\\nfloat sceneMap2( vec3 pos ){\\r\\n\\r\\n\\tfloat angle = u_time/(2.0*3.1415);\\r\\n\\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\\r\\n\\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\\r\\n\\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\\r\\n\\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\\r\\n\\r\\n\\tmat4 northMat = mat4(1.0); \\r\\n\\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 southMat = mat4(1.0); \\r\\n\\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 westMat = mat4(1.0); \\r\\n\\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\\r\\n\\tmat4 eastMat = mat4(1.0); \\r\\n\\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\\r\\n\\r\\n\\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\\r\\n\\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\\r\\n\\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\\r\\n\\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\\r\\n\\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\\r\\n\\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\\r\\n\\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\\r\\n\\t\\r\\n\\t// float dist1;\\r\\n\\t// float bb1 = boxSDF(newPos1, vec3(1.5,1.5,1.5));\\r\\n\\t// if(bb1 < .015)\\r\\n\\t// {\\r\\n\\t// \\tfloat power = 10.0;//12.0 + abs(sin(u_time/4.0))*40.0;\\r\\n\\t// \\tdist1 = SDF_Mandlebulb(newPos1, power);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist1 = bb1;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist2;\\r\\n\\t// float bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1));\\r\\n\\t// if(bb2 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist2 = SDF_Mandlebulb(newPos2, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist2 = bb2;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist3;\\r\\n\\t// float bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t// if(bb3 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist3 = SDF_Mandlebulb(newPos3, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist3 = bb3;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist4;\\r\\n\\t// float bb4 = boxSDF(newPos4, vec3(1.1,1.1,1.1));\\r\\n\\t// if(bb4 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist4 = SDF_Mandlebulb(newPos4, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist4 = bb4;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist5;\\r\\n\\t// float bb5 = boxSDF(newPos5, vec3(1.1,1.1,1.1));\\r\\n\\t// if(bb5 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist5 = SDF_Mandlebulb(newPos5, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist5 = bb5;\\r\\n\\t// }\\r\\n\\r\\n\\t//float man2 = SDF_Mandlebulb(newPos2, 16.0);\\r\\n\\t//float man3 = SDF_Mandlebulb(newPos3, 16.0);\\r\\n\\t//float man4 = SDF_Mandlebulb(newPos4, 16.0);\\r\\n\\t//float man5 = SDF_Mandlebulb(newPos5, 16.0);\\r\\n\\t//float man6 = SDF_Mandlebulb(newPos6, 24.0);\\r\\n\\t//float man7 = SDF_Mandlebulb(newPos7, 24.0);\\r\\n\\t//float man8 = SDF_Mandlebulb(newPos8, 24.0);\\r\\n\\t//float man9 = SDF_Mandlebulb(newPos9, 24.0);\\r\\n\\t\\r\\n\\t//return un(dist1, un(dist2, un(dist3, un(dist4, dist5))));\\r\\n\\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\\r\\n\\r\\n\\tfloat dist1;\\r\\n\\tvec3 newPos1 = transform(transform(pos + vec3(cos((u_time+4.0)/8.0)*4.0, 0, sin(u_time/7.0)*3.5), cwMat), northMat);\\t\\r\\n\\tfloat bb1 = boxSDF(newPos1, vec3(1.1,1.1,1.1));\\r\\n\\tif(bb1 < .015)\\r\\n\\t{\\r\\n\\t\\tfloat power = 12.0;\\r\\n\\t\\tdist1 = SDF_Mandlebulb(newPos1, power);\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdist1 = bb1;\\r\\n\\t}\\r\\n\\r\\n\\tfloat dist2;\\r\\n\\tvec3 newPos2 = transform(transform(pos + vec3(cos((u_time+50.0)/10.0)*2.0, 1, sin((u_time+30.0)/6.0)*2.5), ccwMat), eastMat);\\r\\n\\tfloat bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1));\\r\\n\\tif(bb2 < .015)\\r\\n\\t{\\r\\n\\t\\t\\r\\n\\t\\tfloat power = 12.0;\\r\\n\\t\\tdist2 = SDF_Mandlebulb(newPos2, power);\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdist2 = bb2;\\r\\n\\t}\\r\\n\\r\\n\\tfloat dist3;\\r\\n\\tvec3 newPos3 = transform(transform(pos + vec3(sin((u_time)/16.0)*3.0, -1, cos((u_time+75.0)/3.0)*2.0), cwMat), westMat);\\r\\n\\tfloat bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\tif(bb3 < .015)\\r\\n\\t{\\r\\n\\t\\t\\r\\n\\t\\tfloat power = 12.0;\\r\\n\\t\\tdist3 = SDF_Mandlebulb(newPos3, power);\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdist3 = bb3;\\r\\n\\t}\\r\\n\\r\\n\\treturn un(dist1, un(dist2, dist3));\\r\\n\\r\\n\\t// float dist4;\\r\\n\\t// float bb4 = boxSDF(newPos4, vec3(1.2,1.2,1.2));\\r\\n\\t// if(bb4 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist4 = SDF_Mandlebulb(newPos4, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist4 = bb4;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist5;\\r\\n\\t// float bb5 = boxSDF(newPos5, vec3(1.2,1.2,1.2));\\r\\n\\t// if(bb5 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist5 = SDF_Mandlebulb(newPos5, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist5 = bb5;\\r\\n\\t// }\\r\\n\\t\\r\\n\\t//float man2 = SDF_Mandlebulb(newPos2, 16.0);\\r\\n\\t//float man3 = SDF_Mandlebulb(newPos3, 16.0);\\r\\n\\t//float man4 = SDF_Mandlebulb(newPos4, 16.0);\\r\\n\\t//float man5 = SDF_Mandlebulb(newPos5, 16.0);\\r\\n\\t//float man6 = SDF_Mandlebulb(newPos6, 24.0);\\r\\n\\t//float man7 = SDF_Mandlebulb(newPos7, 24.0);\\r\\n\\t//float man8 = SDF_Mandlebulb(newPos8, 24.0);\\r\\n\\t//float man9 = SDF_Mandlebulb(newPos9, 24.0);\\r\\n\\t// return un(dist1, un(dist2, un(dist3, un(dist4, dist5))));\\r\\n\\t\\r\\n\\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\\r\\n\\t//return dist1;\\r\\n\\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\nvec3 computeNormal( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Check for intersection with the scene for increasing t-values\\r\\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\tfloat dist;\\r\\n\\tfloat t = 0.01;\\r\\n\\tfor(int i = 0; i < 500; i++) {\\r\\n\\t\\tfloat dist = sceneMap2(origin + t * direction);\\r\\n\\t\\tif(dist < 0.0001) {\\r\\n\\t\\t\\treturn vec2(t, 1.0); // intersection\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn vec2(0.0, -1.0); // no intersection\\r\\n}\\r\\n\\r\\n\\r\\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\\r\\n\\tfloat dot = dot(normalize(toCam + toLight), normal);\\r\\n\\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\\r\\n}\\r\\n\\r\\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\\r\\nfloat ComputeAO( vec3 pos, vec3 normal ) {\\r\\n\\tfloat tStep = 0.0025;\\r\\n\\tfloat t = 0.0;\\r\\n\\tfloat ao = 1.0;\\r\\n\\tfloat diff = 0.0;\\r\\n\\tfloat k = 72.0;\\r\\n\\tfor(int i = 0; i < 5; i++) {\\r\\n\\t\\tvec3 sample = pos + t * normal;\\r\\n\\t\\tfloat dist = sceneMap2( sample );\\r\\n\\t\\tdiff += pow(0.5, float (i)) * (t - dist);\\r\\n\\t\\tt += tStep;\\r\\n\\t}\\r\\n\\tao -= clamp(k * diff, 0.0, 1.0);\\r\\n\\treturn ao;\\r\\n}\\r\\n\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n\\t\\r\\n\\t/** Raycasting **/\\r\\n\\t\\r\\n\\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\\r\\n\\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t\\t\\t\\tgl_FragCoord.y / u_resolution.y) - 1.0;\\r\\n\\r\\n\\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\\r\\n\\t//vec3 cameraPos = vec3(1, -4, 2);\\r\\n\\t//vec3 cameraPos = vec3(1, 0, 1);\\r\\n\\t\\r\\n\\t// Circle the origin (0, 0, 0)\\r\\n\\t// cameraPos.x = sin(u_time) * 10.0;\\r\\n\\t// cameraPos.z = cos(u_time) * 10.0;\\r\\n\\t\\r\\n\\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\\r\\n\\t\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos);\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\\r\\n\\t\\r\\n\\t// Perform the raymarch\\r\\n\\tvec3 direction = normalize(point_World - cameraPos);\\r\\n\\tvec2 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\t/** Shading and lighting **/\\r\\n\\t\\r\\n\\tif(isect.y > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormal( isectPos );\\r\\n\\t\\t\\r\\n\\t\\t// Lighting\\r\\n\\t\\tvec3 baseMaterial = vec3(0.2, 0.2, 0.2);\\r\\n\\t\\tvec3 trapColor = vec3(resColor.x+(sin((u_time+isectPos.x)/2.0)*0.2), resColor.y-(cos((u_time+isectPos.y)/8.0)*0.5), resColor.z+(cos((u_time-isectPos.z)/2.0)*0.8));\\r\\n\\t\\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\\r\\n\\t\\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\\r\\n\\t\\t\\r\\n\\t\\tvec3 toSun = normalize(sunPos - isectPos);\\r\\n\\t\\t\\r\\n\\t\\tnormal = -normal;\\r\\n\\t\\t\\r\\n\\t\\t// Visibility test\\r\\n\\t\\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\\r\\n\\t\\t// float vis = 1.0;\\r\\n\\t\\t\\r\\n\\t\\t// if(shadowTest.y > 0.0) { // something is blocking this point\\r\\n\\t\\t// \\tvis = 0.0;\\r\\n\\t\\t// }\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t// Phong-ish shading for now\\r\\n\\t\\tfloat spec = SpecHighlight( -look, toSun, normal);\\r\\n\\t\\t\\r\\n\\t\\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\\r\\n\\t\\tfloat ao = ComputeAO(isectPos, normal);\\r\\n\\t\\t\\r\\n\\t\\t// Apply lambertian shading - for now\\r\\n\\t\\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\\r\\n\\t\\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\\r\\n\\t} else {\\r\\n\\t\\t// Background color\\r\\n\\t\\tgl_FragColor = vec4(0.5, 0.5, 0.5, 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/rayMarch-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 17\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file From 10e8c0e0890f14140ee8543c856c0d9747da0b4b Mon Sep 17 00:00:00 2001 From: tabathah Date: Fri, 28 Apr 2017 18:23:13 -0400 Subject: [PATCH 11/20] bounding spheres instead of boxes --- src/glsl/rayMarch-frag.glsl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/glsl/rayMarch-frag.glsl b/src/glsl/rayMarch-frag.glsl index 3bd74a50..28ab5fd5 100644 --- a/src/glsl/rayMarch-frag.glsl +++ b/src/glsl/rayMarch-frag.glsl @@ -218,9 +218,11 @@ float sceneMap2( vec3 pos ){ //return un(dist1, un(dist2, un(dist3, un(dist4, dist5)))); //return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9)))))))); + float t = u_time/16.0; + float dist1; - vec3 newPos1 = transform(transform(pos + vec3(cos((u_time+4.0)/8.0)*4.0, 0, sin(u_time/7.0)*3.5), cwMat), northMat); - float bb1 = boxSDF(newPos1, vec3(1.1,1.1,1.1)); + vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat); + float bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1)); if(bb1 < .015) { float power = 12.0; @@ -232,8 +234,8 @@ float sceneMap2( vec3 pos ){ } float dist2; - vec3 newPos2 = transform(transform(pos + vec3(cos((u_time+50.0)/10.0)*2.0, 1, sin((u_time+30.0)/6.0)*2.5), ccwMat), eastMat); - float bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1)); + vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat); + float bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1)); if(bb2 < .015) { @@ -246,8 +248,8 @@ float sceneMap2( vec3 pos ){ } float dist3; - vec3 newPos3 = transform(transform(pos + vec3(sin((u_time)/16.0)*3.0, -1, cos((u_time+75.0)/3.0)*2.0), cwMat), westMat); - float bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1)); + vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat); + float bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1)); if(bb3 < .015) { @@ -396,7 +398,7 @@ void main() { // Lighting vec3 baseMaterial = vec3(0.2, 0.2, 0.2); - vec3 trapColor = vec3(resColor.x+(sin((u_time+isectPos.x)/2.0)*0.2), resColor.y-(cos((u_time+isectPos.y)/8.0)*0.5), resColor.z+(cos((u_time-isectPos.z)/2.0)*0.8)); + vec3 trapColor = vec3(resColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.2), resColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), resColor.z+(cos((u_time)/2.0-isectPos.x)*0.8)); vec3 sun = vec3(0.5, 0.4, 0.3) * 12.0; vec3 sunPos = vec3(5.0, 5.0, 0.0); From 49d0f918eafb6b5d83a4a3acaefa33206b12d910 Mon Sep 17 00:00:00 2001 From: tabathah Date: Mon, 1 May 2017 20:21:21 -0400 Subject: [PATCH 12/20] scenes set up --- src/glsl/rayMarch-frag.glsl | 305 +++++++++++++++++++----------------- 1 file changed, 162 insertions(+), 143 deletions(-) diff --git a/src/glsl/rayMarch-frag.glsl b/src/glsl/rayMarch-frag.glsl index 28ab5fd5..4ca610df 100644 --- a/src/glsl/rayMarch-frag.glsl +++ b/src/glsl/rayMarch-frag.glsl @@ -1,7 +1,7 @@ #define MAX_GEOMETRY_COUNT 100 #define SPHERE_TRACING true -#define T_MAX 20.0 +#define T_MAX 8.0 /* This is how I'm packing the data struct geometry_t { @@ -101,10 +101,10 @@ float un(float d1, float d2) return min(d1,d2); } -//returns transformed point based on rotation and translation matrix of shape +// Returns transformed point based on rotation and translation matrix of shape vec3 transform(vec3 point, mat4 trans) { - //columns of the rotation matrix transpose + // Columns of the rotation matrix transpose vec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]); vec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]); vec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]); @@ -123,9 +123,28 @@ float sceneMap( vec3 pos ) { return SDF_Sphere( pos, 1.0 ); } +float mod(int num1, int num2) +{ + int div = num1/num2; + return float(num1 - div*num2); +} + +int sceneNum() +{ + float x = u_time; + float cycle = 90.0;// * 20.0; + float t = (mod(x, cycle)/cycle) * 3.0; + if(t <= 1.0) { return 2; } + else if(t <= 2.0) { return 1; } + else { return 3; } +} + float sceneMap2( vec3 pos ){ - float angle = u_time/(2.0*3.1415); + float t = u_time/4.0; + int sceneNumber = sceneNum(); + + float angle = 2.0*t/(2.0*3.1415); mat4 cwMat = mat4(1.0); //transform for moving clockwise cwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime mat4 ccwMat = mat4(1.0); //transform for moving counterclockwise @@ -149,154 +168,105 @@ float sceneMap2( vec3 pos ){ // vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat); // vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat); // vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat); - - // float dist1; - // float bb1 = boxSDF(newPos1, vec3(1.5,1.5,1.5)); - // if(bb1 < .015) - // { - // float power = 10.0;//12.0 + abs(sin(u_time/4.0))*40.0; - // dist1 = SDF_Mandlebulb(newPos1, power); - // } - // else - // { - // dist1 = bb1; - // } - - // float dist2; - // float bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1)); - // if(bb2 < .015) - // { - // dist2 = SDF_Mandlebulb(newPos2, 16.0); - // } - // else - // { - // dist2 = bb2; - // } - - // float dist3; - // float bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1)); - // if(bb3 < .015) - // { - // dist3 = SDF_Mandlebulb(newPos3, 16.0); - // } - // else - // { - // dist3 = bb3; - // } - - // float dist4; - // float bb4 = boxSDF(newPos4, vec3(1.1,1.1,1.1)); - // if(bb4 < .015) - // { - // dist4 = SDF_Mandlebulb(newPos4, 16.0); - // } - // else - // { - // dist4 = bb4; - // } - - // float dist5; - // float bb5 = boxSDF(newPos5, vec3(1.1,1.1,1.1)); - // if(bb5 < .015) - // { - // dist5 = SDF_Mandlebulb(newPos5, 16.0); - // } - // else - // { - // dist5 = bb5; - // } - - //float man2 = SDF_Mandlebulb(newPos2, 16.0); - //float man3 = SDF_Mandlebulb(newPos3, 16.0); - //float man4 = SDF_Mandlebulb(newPos4, 16.0); - //float man5 = SDF_Mandlebulb(newPos5, 16.0); - //float man6 = SDF_Mandlebulb(newPos6, 24.0); - //float man7 = SDF_Mandlebulb(newPos7, 24.0); - //float man8 = SDF_Mandlebulb(newPos8, 24.0); - //float man9 = SDF_Mandlebulb(newPos9, 24.0); - - //return un(dist1, un(dist2, un(dist3, un(dist4, dist5)))); - //return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9)))))))); - float t = u_time/16.0; - - float dist1; - vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat); - float bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1)); - if(bb1 < .015) - { - float power = 12.0; - dist1 = SDF_Mandlebulb(newPos1, power); - } - else + if(sceneNumber == 1) { - dist1 = bb1; - } + //SCENE 01------------------------------------------------------------ + float dist1; + //vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat); + vec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), cwMat), northMat); + float bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1)); + if(bb1 < .015) + { + float power = 10.0; + dist1 = SDF_Mandlebulb(newPos1, power); + } + else + { + dist1 = bb1; + } - float dist2; - vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat); - float bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1)); - if(bb2 < .015) - { + float dist2; + //vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat); + vec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), ccwMat), eastMat); + float bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1)); + if(bb2 < .015) + { + float power = 10.0; + dist2 = SDF_Mandlebulb(newPos2, power); + } + else + { + dist2 = bb2; + } + + float dist3; + // vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat); + vec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -0.5*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat); + float bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1)); + if(bb3 < .015) + { - float power = 12.0; - dist2 = SDF_Mandlebulb(newPos2, power); + float power = 10.0; + dist3 = SDF_Mandlebulb(newPos3, power); + } + else + { + dist3 = bb3; + } + + return un(dist1, un(dist2, dist3)); } - else + else if(sceneNumber == 2) { - dist2 = bb2; - } + //SCENE 02------------------------------------------------------------ + float dist4; + mat4 rotateX = mat4(1.0); rotateX[1][1] = 0.0; rotateX[1][2] = 1.0; rotateX[2][1] = -1.0; rotateX[2][2] = 0.0; //rotate 90 degress about x-axis + float angY = 45.0*3.1415/180.0; + mat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis + float angZ = (2.0*u_time)*3.1415/180.0; + mat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis + float displace = mod(u_time, 90.0)/30.0*3.0; + vec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX); + float bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1)); + if(bb4 < .015) + { + float power = 10.0; + dist4 = SDF_Mandlebulb(newPos4, power); + } + else + { + dist4 = bb4; + } - float dist3; - vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat); - float bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1)); - if(bb3 < .015) - { - - float power = 12.0; - dist3 = SDF_Mandlebulb(newPos3, power); + return dist4; } - else + else { - dist3 = bb3; - } + //SCENE 03------------------------------------------------------------ + float dist5; + mat4 rotateX2 = mat4(1.0); rotateX2[1][1] = 0.0; rotateX2[1][2] = 1.0; rotateX2[2][1] = -1.0; rotateX2[2][2] = 0.0; //rotate 90 degress about x-axis + float angY2 = -45.0*3.1415/180.0; + mat4 rotateY2 = mat4(1.0); rotateY2[0][0] = cos(angY2); rotateY2[0][2] = -sin(angY2); rotateY2[2][0] = sin(angY2); rotateY2[2][2] = cos(angY2); //rotate 45 degrees about y-axis + float angZ2 = (2.0*u_time)*3.1415/180.0; + mat4 rotateZ2 = mat4(1.0); rotateZ2[0][0] = cos(angZ2); rotateZ2[0][2] = -sin(angZ2); rotateZ2[2][0] = sin(angZ2); rotateZ2[2][2] = cos(angZ2); //spin about y-axis + vec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), rotateY2), rotateX2), rotateZ2); + float bb5 = SDF_Sphere(newPos5, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1)); + if(bb5 < .015) + { + float power = 10.0; + dist5 = SDF_Mandlebulb(newPos5, power); + } + else + { + dist5 = bb5; + } - return un(dist1, un(dist2, dist3)); - - // float dist4; - // float bb4 = boxSDF(newPos4, vec3(1.2,1.2,1.2)); - // if(bb4 < .015) - // { - // dist4 = SDF_Mandlebulb(newPos4, 16.0); - // } - // else - // { - // dist4 = bb4; - // } - - // float dist5; - // float bb5 = boxSDF(newPos5, vec3(1.2,1.2,1.2)); - // if(bb5 < .015) - // { - // dist5 = SDF_Mandlebulb(newPos5, 16.0); - // } - // else - // { - // dist5 = bb5; - // } - - //float man2 = SDF_Mandlebulb(newPos2, 16.0); - //float man3 = SDF_Mandlebulb(newPos3, 16.0); - //float man4 = SDF_Mandlebulb(newPos4, 16.0); - //float man5 = SDF_Mandlebulb(newPos5, 16.0); - //float man6 = SDF_Mandlebulb(newPos6, 24.0); - //float man7 = SDF_Mandlebulb(newPos7, 24.0); - //float man8 = SDF_Mandlebulb(newPos8, 24.0); - //float man9 = SDF_Mandlebulb(newPos9, 24.0); - // return un(dist1, un(dist2, un(dist3, un(dist4, dist5)))); + return dist5; + } // dist1 = SDF_Mandlebulb(newPos1, 12.0); - //return dist1; + //return dist3; //return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9)))))))); } @@ -354,6 +324,37 @@ float ComputeAO( vec3 pos, vec3 normal ) { } +vec3 backgroundColor() +{ + int sn = sceneNum(); + float darken; + if(sn == 1) + { + darken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0)); + darken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0)); + } + else if(sn == 2) + { + darken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time)); + } + else + { + darken = cos(length(f_uv - vec2(0.5, 0.5))); + darken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5; + } + + darken = clamp(darken, 0.2, 1.0); + + vec3 a = vec3(0.5, 0.5, 0.5); + vec3 b = vec3(0.5, 0.5, 0.5); + vec3 c = vec3(2.0, 1.0, 1.0); + vec3 d = vec3(0.5, 0.2, 0.25); + float t = abs(sin(u_time/12.0)); + vec3 color = a + b*cos(6.28*(c*t + d)); + + return darken*color; +} + void main() { @@ -397,8 +398,24 @@ void main() { vec3 normal = computeNormal( isectPos ); // Lighting - vec3 baseMaterial = vec3(0.2, 0.2, 0.2); - vec3 trapColor = vec3(resColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.2), resColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), resColor.z+(cos((u_time)/2.0-isectPos.x)*0.8)); + vec3 baseMaterial = vec3(0.1, 0.2, 0.2); + vec3 trapColor; + int sn = sceneNum(); + if(sn == 1) + { + trapColor = vec3( + resColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.8), + resColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), + resColor.z+(cos((u_time)/2.0-isectPos.x)*0.2)); + } + else if(sn == 2) + { + trapColor = vec3(resColor) + vec3(0.4); + } + else + { + trapColor = vec3(0.0, resColor.y+0.4, resColor.z+0.4); + } vec3 sun = vec3(0.5, 0.4, 0.3) * 12.0; vec3 sunPos = vec3(5.0, 5.0, 0.0); @@ -423,10 +440,12 @@ void main() { float ao = ComputeAO(isectPos, normal); // Apply lambertian shading - for now + + //gl_FragColor = ao*vec4(baseMaterial, 1.0); gl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1); //gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1); } else { // Background color - gl_FragColor = vec4(0.5, 0.5, 0.5, 1); + gl_FragColor = vec4(backgroundColor(), 1); } } From 42352e2c2e4041381c9c1ddd1794a0c404bd741f Mon Sep 17 00:00:00 2001 From: tabathah Date: Mon, 1 May 2017 20:22:25 -0400 Subject: [PATCH 13/20] random package thing got changed --- build/bundle.js | 2 +- build/bundle.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/bundle.js b/build/bundle.js index 4371c5b5..a7e03530 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -48470,7 +48470,7 @@ /* 15 */ /***/ (function(module, exports) { - module.exports = "\r\n#define MAX_GEOMETRY_COUNT 100\r\n#define SPHERE_TRACING true\r\n#define T_MAX 20.0\r\n\r\n/* This is how I'm packing the data\r\nstruct geometry_t {\r\n vec3 position;\r\n float type;\r\n};\r\n*/\r\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\r\n// uniform int u_count;\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\nvec4 resColor;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t *****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\n//diagonal is the vector from the center of the box to the first quadrant corner\r\nfloat boxSDF(vec3 point, vec3 diagonal) {\r\n\tvec3 d = abs(point) - diagonal;\r\n \treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\r\n}\r\n\r\nfloat SDF_Mandlebulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i=0; i<4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n resColor = trap;\r\n\r\n return 0.25*log(m)*sqrt(m)/dz;\r\n}\r\n\r\n//Operators:\r\n\r\nfloat intersection(float d1, float d2)\r\n{\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 )\r\n{\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2)\r\n{\r\n return min(d1,d2);\r\n}\r\n\r\n//returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform(vec3 point, mat4 trans)\r\n{\r\n\t//columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\n// Return the distance of the closest object in the scene\r\nfloat sceneMap( vec3 pos ) {\r\n\treturn SDF_Sphere( pos, 1.0 );\r\n}\r\n\r\nfloat sceneMap2( vec3 pos ){\r\n\r\n\tfloat angle = u_time/(2.0*3.1415);\r\n\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\r\n\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\r\n\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\r\n\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\r\n\r\n\tmat4 northMat = mat4(1.0); \r\n\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\r\n\tmat4 southMat = mat4(1.0); \r\n\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\r\n\tmat4 westMat = mat4(1.0); \r\n\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\r\n\tmat4 eastMat = mat4(1.0); \r\n\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\r\n\r\n\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\r\n\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\r\n\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\r\n\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\r\n\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\r\n\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\r\n\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\r\n\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\r\n\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\r\n\t\r\n\t// float dist1;\r\n\t// float bb1 = boxSDF(newPos1, vec3(1.5,1.5,1.5));\r\n\t// if(bb1 < .015)\r\n\t// {\r\n\t// \tfloat power = 10.0;//12.0 + abs(sin(u_time/4.0))*40.0;\r\n\t// \tdist1 = SDF_Mandlebulb(newPos1, power);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist1 = bb1;\r\n\t// }\r\n\r\n\t// float dist2;\r\n\t// float bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1));\r\n\t// if(bb2 < .015)\r\n\t// {\r\n\t// \tdist2 = SDF_Mandlebulb(newPos2, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist2 = bb2;\r\n\t// }\r\n\r\n\t// float dist3;\r\n\t// float bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t// if(bb3 < .015)\r\n\t// {\r\n\t// \tdist3 = SDF_Mandlebulb(newPos3, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist3 = bb3;\r\n\t// }\r\n\r\n\t// float dist4;\r\n\t// float bb4 = boxSDF(newPos4, vec3(1.1,1.1,1.1));\r\n\t// if(bb4 < .015)\r\n\t// {\r\n\t// \tdist4 = SDF_Mandlebulb(newPos4, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist4 = bb4;\r\n\t// }\r\n\r\n\t// float dist5;\r\n\t// float bb5 = boxSDF(newPos5, vec3(1.1,1.1,1.1));\r\n\t// if(bb5 < .015)\r\n\t// {\r\n\t// \tdist5 = SDF_Mandlebulb(newPos5, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist5 = bb5;\r\n\t// }\r\n\r\n\t//float man2 = SDF_Mandlebulb(newPos2, 16.0);\r\n\t//float man3 = SDF_Mandlebulb(newPos3, 16.0);\r\n\t//float man4 = SDF_Mandlebulb(newPos4, 16.0);\r\n\t//float man5 = SDF_Mandlebulb(newPos5, 16.0);\r\n\t//float man6 = SDF_Mandlebulb(newPos6, 24.0);\r\n\t//float man7 = SDF_Mandlebulb(newPos7, 24.0);\r\n\t//float man8 = SDF_Mandlebulb(newPos8, 24.0);\r\n\t//float man9 = SDF_Mandlebulb(newPos9, 24.0);\r\n\t\r\n\t//return un(dist1, un(dist2, un(dist3, un(dist4, dist5))));\r\n\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\r\n\r\n\tfloat dist1;\r\n\tvec3 newPos1 = transform(transform(pos + vec3(cos((u_time+4.0)/8.0)*4.0, 0, sin(u_time/7.0)*3.5), cwMat), northMat);\t\r\n\tfloat bb1 = boxSDF(newPos1, vec3(1.1,1.1,1.1));\r\n\tif(bb1 < .015)\r\n\t{\r\n\t\tfloat power = 12.0;\r\n\t\tdist1 = SDF_Mandlebulb(newPos1, power);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdist1 = bb1;\r\n\t}\r\n\r\n\tfloat dist2;\r\n\tvec3 newPos2 = transform(transform(pos + vec3(cos((u_time+50.0)/10.0)*2.0, 1, sin((u_time+30.0)/6.0)*2.5), ccwMat), eastMat);\r\n\tfloat bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1));\r\n\tif(bb2 < .015)\r\n\t{\r\n\t\t\r\n\t\tfloat power = 12.0;\r\n\t\tdist2 = SDF_Mandlebulb(newPos2, power);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdist2 = bb2;\r\n\t}\r\n\r\n\tfloat dist3;\r\n\tvec3 newPos3 = transform(transform(pos + vec3(sin((u_time)/16.0)*3.0, -1, cos((u_time+75.0)/3.0)*2.0), cwMat), westMat);\r\n\tfloat bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\tif(bb3 < .015)\r\n\t{\r\n\t\t\r\n\t\tfloat power = 12.0;\r\n\t\tdist3 = SDF_Mandlebulb(newPos3, power);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdist3 = bb3;\r\n\t}\r\n\r\n\treturn un(dist1, un(dist2, dist3));\r\n\r\n\t// float dist4;\r\n\t// float bb4 = boxSDF(newPos4, vec3(1.2,1.2,1.2));\r\n\t// if(bb4 < .015)\r\n\t// {\r\n\t// \tdist4 = SDF_Mandlebulb(newPos4, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist4 = bb4;\r\n\t// }\r\n\r\n\t// float dist5;\r\n\t// float bb5 = boxSDF(newPos5, vec3(1.2,1.2,1.2));\r\n\t// if(bb5 < .015)\r\n\t// {\r\n\t// \tdist5 = SDF_Mandlebulb(newPos5, 16.0);\r\n\t// }\r\n\t// else\r\n\t// {\r\n\t// \tdist5 = bb5;\r\n\t// }\r\n\t\r\n\t//float man2 = SDF_Mandlebulb(newPos2, 16.0);\r\n\t//float man3 = SDF_Mandlebulb(newPos3, 16.0);\r\n\t//float man4 = SDF_Mandlebulb(newPos4, 16.0);\r\n\t//float man5 = SDF_Mandlebulb(newPos5, 16.0);\r\n\t//float man6 = SDF_Mandlebulb(newPos6, 24.0);\r\n\t//float man7 = SDF_Mandlebulb(newPos7, 24.0);\r\n\t//float man8 = SDF_Mandlebulb(newPos8, 24.0);\r\n\t//float man9 = SDF_Mandlebulb(newPos9, 24.0);\r\n\t// return un(dist1, un(dist2, un(dist3, un(dist4, dist5))));\r\n\t\r\n\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\r\n\t//return dist1;\r\n\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\nvec3 computeNormal( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\r\n\t\t\t\t\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\r\n\t\t\t\t\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\r\n\treturn normal;\r\n}\r\n\r\n// Check for intersection with the scene for increasing t-values\r\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\r\n\tfloat dist;\r\n\tfloat t = 0.01;\r\n\tfor(int i = 0; i < 500; i++) {\r\n\t\tfloat dist = sceneMap2(origin + t * direction);\r\n\t\tif(dist < 0.0001) {\r\n\t\t\treturn vec2(t, 1.0); // intersection\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn vec2(0.0, -1.0); // no intersection\r\n}\r\n\r\n\r\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\r\n\tfloat dot = dot(normalize(toCam + toLight), normal);\r\n\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\r\n}\r\n\r\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\r\nfloat ComputeAO( vec3 pos, vec3 normal ) {\r\n\tfloat tStep = 0.0025;\r\n\tfloat t = 0.0;\r\n\tfloat ao = 1.0;\r\n\tfloat diff = 0.0;\r\n\tfloat k = 72.0;\r\n\tfor(int i = 0; i < 5; i++) {\r\n\t\tvec3 sample = pos + t * normal;\r\n\t\tfloat dist = sceneMap2( sample );\r\n\t\tdiff += pow(0.5, float (i)) * (t - dist);\r\n\t\tt += tStep;\r\n\t}\r\n\tao -= clamp(k * diff, 0.0, 1.0);\r\n\treturn ao;\r\n}\r\n\r\n\r\n\r\nvoid main() {\r\n\t\r\n\t/** Raycasting **/\r\n\t\r\n\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\r\n\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\r\n\t\t\t\t\t\t\t\tgl_FragCoord.y / u_resolution.y) - 1.0;\r\n\r\n\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\r\n\t//vec3 cameraPos = vec3(1, -4, 2);\r\n\t//vec3 cameraPos = vec3(1, 0, 1);\r\n\t\r\n\t// Circle the origin (0, 0, 0)\r\n\t// cameraPos.x = sin(u_time) * 10.0;\r\n\t// cameraPos.z = cos(u_time) * 10.0;\r\n\t\r\n\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\r\n\t\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos);\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\r\n\t\r\n\t// Perform the raymarch\r\n\tvec3 direction = normalize(point_World - cameraPos);\r\n\tvec2 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\t/** Shading and lighting **/\r\n\t\r\n\tif(isect.y > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormal( isectPos );\r\n\t\t\r\n\t\t// Lighting\r\n\t\tvec3 baseMaterial = vec3(0.2, 0.2, 0.2);\r\n\t\tvec3 trapColor = vec3(resColor.x+(sin((u_time+isectPos.x)/2.0)*0.2), resColor.y-(cos((u_time+isectPos.y)/8.0)*0.5), resColor.z+(cos((u_time-isectPos.z)/2.0)*0.8));\r\n\t\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\r\n\t\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\r\n\t\t\r\n\t\tvec3 toSun = normalize(sunPos - isectPos);\r\n\t\t\r\n\t\tnormal = -normal;\r\n\t\t\r\n\t\t// Visibility test\r\n\t\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\r\n\t\t// float vis = 1.0;\r\n\t\t\r\n\t\t// if(shadowTest.y > 0.0) { // something is blocking this point\r\n\t\t// \tvis = 0.0;\r\n\t\t// }\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t// Phong-ish shading for now\r\n\t\tfloat spec = SpecHighlight( -look, toSun, normal);\r\n\t\t\r\n\t\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\r\n\t\tfloat ao = ComputeAO(isectPos, normal);\r\n\t\t\r\n\t\t// Apply lambertian shading - for now\r\n\t\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\r\n\t\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\r\n\t} else {\r\n\t\t// Background color\r\n\t\tgl_FragColor = vec4(0.5, 0.5, 0.5, 1);\r\n\t}\r\n}\r\n" + module.exports = "\r\n#define MAX_GEOMETRY_COUNT 100\r\n#define SPHERE_TRACING true\r\n#define T_MAX 8.0\r\n\r\n/* This is how I'm packing the data\r\nstruct geometry_t {\r\n vec3 position;\r\n float type;\r\n};\r\n*/\r\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\r\n// uniform int u_count;\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\nvec4 resColor;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t *****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\n//diagonal is the vector from the center of the box to the first quadrant corner\r\nfloat boxSDF(vec3 point, vec3 diagonal) {\r\n\tvec3 d = abs(point) - diagonal;\r\n \treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\r\n}\r\n\r\nfloat SDF_Mandlebulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i=0; i<4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n resColor = trap;\r\n\r\n return 0.25*log(m)*sqrt(m)/dz;\r\n}\r\n\r\n//Operators:\r\n\r\nfloat intersection(float d1, float d2)\r\n{\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 )\r\n{\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2)\r\n{\r\n return min(d1,d2);\r\n}\r\n\r\n// Returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform(vec3 point, mat4 trans)\r\n{\r\n\t// Columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\n// Return the distance of the closest object in the scene\r\nfloat sceneMap( vec3 pos ) {\r\n\treturn SDF_Sphere( pos, 1.0 );\r\n}\r\n\r\nfloat mod(int num1, int num2)\r\n{\r\n\tint div = num1/num2;\r\n\treturn float(num1 - div*num2);\r\n}\r\n\r\nint sceneNum()\r\n{\r\n\tfloat x = u_time;\r\n\tfloat cycle = 90.0;// * 20.0;\r\n\tfloat t = (mod(x, cycle)/cycle) * 3.0;\r\n\tif(t <= 1.0) { return 2; }\r\n\telse if(t <= 2.0) { return 1; }\r\n\telse { return 3; }\r\n}\r\n\r\nfloat sceneMap2( vec3 pos ){\r\n\r\n\tfloat t = u_time/4.0;\r\n\tint sceneNumber = sceneNum();\r\n\r\n\tfloat angle = 2.0*t/(2.0*3.1415);\r\n\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\r\n\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\r\n\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\r\n\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\r\n\r\n\tmat4 northMat = mat4(1.0); \r\n\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\r\n\tmat4 southMat = mat4(1.0); \r\n\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\r\n\tmat4 westMat = mat4(1.0); \r\n\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\r\n\tmat4 eastMat = mat4(1.0); \r\n\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\r\n\r\n\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\r\n\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\r\n\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\r\n\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\r\n\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\r\n\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\r\n\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\r\n\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\r\n\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\r\n\r\n\tif(sceneNumber == 1)\r\n\t{\r\n\t\t//SCENE 01------------------------------------------------------------\r\n\t\tfloat dist1;\r\n\t\t//vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat);\r\n\t\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), cwMat), northMat);\t\r\n\t\tfloat bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1));\r\n\t\tif(bb1 < .015)\r\n\t\t{\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist1 = SDF_Mandlebulb(newPos1, power);\r\n\t\t}\t\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist1 = bb1;\r\n\t\t}\r\n\r\n\t\tfloat dist2;\r\n\t\t//vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat);\r\n\t\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), ccwMat), eastMat);\t\r\n\t\tfloat bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1));\r\n\t\tif(bb2 < .015)\r\n\t\t{\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist2 = SDF_Mandlebulb(newPos2, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist2 = bb2;\r\n\t\t}\r\n\r\n\t\tfloat dist3;\r\n\t\t// vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat);\r\n\t\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -0.5*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat);\t\r\n\t\tfloat bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb3 < .015)\r\n\t\t{\r\n\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist3 = SDF_Mandlebulb(newPos3, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist3 = bb3;\r\n\t\t}\r\n\r\n\t\treturn un(dist1, un(dist2, dist3));\r\n\t}\r\n\telse if(sceneNumber == 2)\r\n\t{\r\n\t\t//SCENE 02------------------------------------------------------------\r\n\t\tfloat dist4;\r\n\t\tmat4 rotateX = mat4(1.0); rotateX[1][1] = 0.0; rotateX[1][2] = 1.0; rotateX[2][1] = -1.0; rotateX[2][2] = 0.0; //rotate 90 degress about x-axis\r\n\t\tfloat angY = 45.0*3.1415/180.0;\r\n\t\tmat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis\r\n\t\tfloat angZ = (2.0*u_time)*3.1415/180.0;\r\n\t\tmat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis\r\n\t\tfloat displace = mod(u_time, 90.0)/30.0*3.0; \r\n\t\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX);\t\r\n\t\tfloat bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb4 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist4 = SDF_Mandlebulb(newPos4, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist4 = bb4;\r\n\t\t}\r\n\r\n\t\treturn dist4;\r\n\t}\r\n\telse \r\n\t{\r\n\t\t//SCENE 03------------------------------------------------------------\r\n\t\tfloat dist5;\r\n\t\tmat4 rotateX2 = mat4(1.0); rotateX2[1][1] = 0.0; rotateX2[1][2] = 1.0; rotateX2[2][1] = -1.0; rotateX2[2][2] = 0.0; //rotate 90 degress about x-axis\r\n\t\tfloat angY2 = -45.0*3.1415/180.0;\r\n\t\tmat4 rotateY2 = mat4(1.0); rotateY2[0][0] = cos(angY2); rotateY2[0][2] = -sin(angY2); rotateY2[2][0] = sin(angY2); rotateY2[2][2] = cos(angY2); //rotate 45 degrees about y-axis\r\n\t\tfloat angZ2 = (2.0*u_time)*3.1415/180.0;\r\n\t\tmat4 rotateZ2 = mat4(1.0); rotateZ2[0][0] = cos(angZ2); rotateZ2[0][2] = -sin(angZ2); rotateZ2[2][0] = sin(angZ2); rotateZ2[2][2] = cos(angZ2); //spin about y-axis\r\n\t\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), rotateY2), rotateX2), rotateZ2);\t\r\n\t\tfloat bb5 = SDF_Sphere(newPos5, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb5 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist5 = SDF_Mandlebulb(newPos5, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist5 = bb5;\r\n\t\t}\r\n\r\n\t\treturn dist5;\r\n\t}\r\n\t\r\n\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\r\n\t//return dist3;\r\n\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\nvec3 computeNormal( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\r\n\t\t\t\t\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\r\n\t\t\t\t\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\r\n\treturn normal;\r\n}\r\n\r\n// Check for intersection with the scene for increasing t-values\r\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\r\n\tfloat dist;\r\n\tfloat t = 0.01;\r\n\tfor(int i = 0; i < 500; i++) {\r\n\t\tfloat dist = sceneMap2(origin + t * direction);\r\n\t\tif(dist < 0.0001) {\r\n\t\t\treturn vec2(t, 1.0); // intersection\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn vec2(0.0, -1.0); // no intersection\r\n}\r\n\r\n\r\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\r\n\tfloat dot = dot(normalize(toCam + toLight), normal);\r\n\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\r\n}\r\n\r\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\r\nfloat ComputeAO( vec3 pos, vec3 normal ) {\r\n\tfloat tStep = 0.0025;\r\n\tfloat t = 0.0;\r\n\tfloat ao = 1.0;\r\n\tfloat diff = 0.0;\r\n\tfloat k = 72.0;\r\n\tfor(int i = 0; i < 5; i++) {\r\n\t\tvec3 sample = pos + t * normal;\r\n\t\tfloat dist = sceneMap2( sample );\r\n\t\tdiff += pow(0.5, float (i)) * (t - dist);\r\n\t\tt += tStep;\r\n\t}\r\n\tao -= clamp(k * diff, 0.0, 1.0);\r\n\treturn ao;\r\n}\r\n\r\n\r\nvec3 backgroundColor()\r\n{\r\n\tint sn = sceneNum();\r\n\tfloat darken; \r\n\tif(sn == 1)\r\n\t{\r\n\t\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\r\n\t\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\r\n\t}\r\n\telse if(sn == 2)\r\n\t{\r\n\t\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\r\n\t\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\r\n\t}\r\n\t\r\n\tdarken = clamp(darken, 0.2, 1.0);\r\n\r\n\tvec3 a = vec3(0.5, 0.5, 0.5);\r\n\tvec3 b = vec3(0.5, 0.5, 0.5);\r\n\tvec3 c = vec3(2.0, 1.0, 1.0);\r\n\tvec3 d = vec3(0.5, 0.2, 0.25);\r\n\tfloat t = abs(sin(u_time/12.0));\r\n\tvec3 color = a + b*cos(6.28*(c*t + d));\r\n\r\n\treturn darken*color;\r\n}\r\n\r\n\r\nvoid main() {\r\n\t\r\n\t/** Raycasting **/\r\n\t\r\n\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\r\n\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\r\n\t\t\t\t\t\t\t\tgl_FragCoord.y / u_resolution.y) - 1.0;\r\n\r\n\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\r\n\t//vec3 cameraPos = vec3(1, -4, 2);\r\n\t//vec3 cameraPos = vec3(1, 0, 1);\r\n\t\r\n\t// Circle the origin (0, 0, 0)\r\n\t// cameraPos.x = sin(u_time) * 10.0;\r\n\t// cameraPos.z = cos(u_time) * 10.0;\r\n\t\r\n\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\r\n\t\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos);\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\r\n\t\r\n\t// Perform the raymarch\r\n\tvec3 direction = normalize(point_World - cameraPos);\r\n\tvec2 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\t/** Shading and lighting **/\r\n\t\r\n\tif(isect.y > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormal( isectPos );\r\n\t\t\r\n\t\t// Lighting\r\n\t\tvec3 baseMaterial = vec3(0.1, 0.2, 0.2);\r\n\t\tvec3 trapColor;\r\n\t\tint sn = sceneNum();\r\n\t\tif(sn == 1)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(\r\n\t\t\t\tresColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.8), \r\n\t\t\t\tresColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), \r\n\t\t\t\tresColor.z+(cos((u_time)/2.0-isectPos.x)*0.2));\r\n\t\t}\r\n\t\telse if(sn == 2)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(resColor) + vec3(0.4);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\ttrapColor = vec3(0.0, resColor.y+0.4, resColor.z+0.4);\r\n\t\t}\r\n\t\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\r\n\t\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\r\n\t\t\r\n\t\tvec3 toSun = normalize(sunPos - isectPos);\r\n\t\t\r\n\t\tnormal = -normal;\r\n\t\t\r\n\t\t// Visibility test\r\n\t\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\r\n\t\t// float vis = 1.0;\r\n\t\t\r\n\t\t// if(shadowTest.y > 0.0) { // something is blocking this point\r\n\t\t// \tvis = 0.0;\r\n\t\t// }\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t// Phong-ish shading for now\r\n\t\tfloat spec = SpecHighlight( -look, toSun, normal);\r\n\t\t\r\n\t\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\r\n\t\tfloat ao = ComputeAO(isectPos, normal);\r\n\t\t\r\n\t\t// Apply lambertian shading - for now\r\n\t\t\r\n\t\t//gl_FragColor = ao*vec4(baseMaterial, 1.0);\r\n\t\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\r\n\t\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\r\n\t} else {\r\n\t\t// Background color\r\n\t\tgl_FragColor = vec4(backgroundColor(), 1);\r\n\t}\r\n}\r\n" /***/ }), /* 16 */ diff --git a/build/bundle.js.map b/build/bundle.js.map index 724b673f..c4da971e 100644 --- a/build/bundle.js.map +++ b/build/bundle.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 3aae6504ba570c47e9d2","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/rayMarch-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","aspect","updateProjectionMatrix","gui","GUI","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","buffer","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","composer","shaderPass","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","vertexShader","fragmentShader","renderToScreen","addPass","getElapsedTime"],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;;;ACjCA;;;;AACA;;;;AACA;;;;AACA;;;;;;AARA,oBAAAA,CAAQ,EAAR;;AAEA,KAAMC,QAAQ,mBAAAD,CAAQ,CAAR,CAAd;AACA,KAAME,gBAAgB,mBAAAF,CAAQ,EAAR,EAAgCC,KAAhC,CAAtB;;AAOA,KAAIE,cAAc,IAAIF,MAAME,WAAV,CAAsB,CAAtB,EAAyB,CAAzB,EAA4B,CAA5B,CAAlB;AACA,KAAIC,iBAAiB,IAAIH,MAAMG,cAAV,CAAyB,CAAzB,EAA4B,EAA5B,EAAgC,EAAhC,CAArB;AACA,KAAIC,eAAe,IAAIJ,MAAMI,YAAV,CAAuB,CAAvB,EAA0B,CAA1B,CAAnB;;AAEA,KAAIC,QAAQ,IAAIL,MAAMM,KAAV,EAAZ;;AAEAC,QAAOC,gBAAP,CAAwB,MAAxB,EAAgC,YAAW;AACvC,SAAIC,QAAQ,uBAAZ;AACAA,WAAMC,OAAN,CAAc,CAAd;AACAD,WAAME,UAAN,CAAiBC,KAAjB,CAAuBC,QAAvB,GAAkC,UAAlC;AACAJ,WAAME,UAAN,CAAiBC,KAAjB,CAAuBE,IAAvB,GAA8B,KAA9B;AACAL,WAAME,UAAN,CAAiBC,KAAjB,CAAuBG,GAAvB,GAA6B,KAA7B;AACAC,cAASC,IAAT,CAAcC,WAAd,CAA0BT,MAAME,UAAhC;;AAEA,SAAIQ,QAAQ,IAAInB,MAAMoB,KAAV,EAAZ;AACA,SAAIC,SAAS,IAAIrB,MAAMsB,iBAAV,CAA6B,EAA7B,EAAiCf,OAAOgB,UAAP,GAAkBhB,OAAOiB,WAA1D,EAAuE,GAAvE,EAA4E,IAA5E,CAAb;AACA,SAAIC,WAAW,IAAIzB,MAAM0B,aAAV,CAAyB,EAAEC,WAAW,IAAb,EAAzB,CAAf;AACAF,cAASG,aAAT,CAAuBrB,OAAOsB,gBAA9B;AACAJ,cAASK,OAAT,CAAiBvB,OAAOgB,UAAxB,EAAoChB,OAAOiB,WAA3C;AACAC,cAASM,aAAT,CAAuB,QAAvB,EAAiC,GAAjC;AACAf,cAASC,IAAT,CAAcC,WAAd,CAA0BO,SAASd,UAAnC;;AAEA,SAAIqB,WAAW,IAAI/B,aAAJ,CAAkBoB,MAAlB,EAA0BI,SAASd,UAAnC,CAAf;AACAqB,cAASC,aAAT,GAAyB,IAAzB;AACAD,cAASE,UAAT,GAAsB,IAAtB;AACAF,cAASG,WAAT,GAAuB,GAAvB;AACAH,cAASI,SAAT,GAAqB,GAArB;AACAJ,cAASK,QAAT,GAAoB,GAApB;;AAEA9B,YAAOC,gBAAP,CAAwB,QAAxB,EAAkC,YAAW;AACzCa,gBAAOiB,MAAP,GAAgB/B,OAAOgB,UAAP,GAAoBhB,OAAOiB,WAA3C;AACAH,gBAAOkB,sBAAP;AACAd,kBAASK,OAAT,CAAiBvB,OAAOgB,UAAxB,EAAoChB,OAAOiB,WAA3C;AACH,MAJD;;AAMA,SAAIgB,MAAM,IAAI,iBAAIC,GAAR,EAAV;;AAEA,SAAIC,UAAU;AACVC,mBAAU;AADA,MAAd;;AAIAH,SAAII,GAAJ,CAAQF,OAAR,EAAiB,UAAjB,EAA6B,CAAC,gBAAD,EAAmB,cAAnB,CAA7B;;AAEAvB,WAAMyB,GAAN,CAAU,IAAI5C,MAAM6C,UAAV,CAAqB,EAArB,CAAV;AACA1B,WAAMyB,GAAN,CAAU,IAAI5C,MAAM8C,gBAAV,CAA2B,QAA3B,EAAqC,CAArC,CAAV;;AAEA,SAAIC,gBAAgB,8BAApB;;AAEA,SAAIC,UAAU,IAAIhD,MAAMiD,IAAV,CAAe/C,WAAf,gCAAd;AACA,SAAIgD,aAAa,IAAIlD,MAAMiD,IAAV,CAAe9C,cAAf,gCAAjB;AACA,SAAIgD,WAAW,IAAInD,MAAMiD,IAAV,CAAe7C,YAAf,gCAAf;;AAEA4C,aAAQnC,QAAR,CAAiBuC,GAAjB,CAAqB,CAAC,CAAtB,EAAyB,CAAzB,EAA4B,CAA5B;AACAD,cAAStC,QAAT,CAAkBuC,GAAlB,CAAsB,CAAtB,EAAyB,CAAzB,EAA4B,CAA5B;;AAEAL,mBAAcH,GAAd,CAAkBI,OAAlB;AACAD,mBAAcH,GAAd,CAAkBM,UAAlB;AACAH,mBAAcH,GAAd,CAAkBO,QAAlB;;AAEAhC,WAAMyB,GAAN,CAAUG,cAAcM,KAAxB;;AAEAhC,YAAOR,QAAP,CAAgBuC,GAAhB,CAAoB,CAApB,EAAuB,EAAvB,EAA2B,EAA3B;AACA/B,YAAOiC,MAAP,CAAc,IAAItD,MAAMuD,OAAV,CAAkB,CAAlB,EAAoB,CAApB,EAAsB,CAAtB,CAAd;AACAvB,cAASwB,MAAT,CAAgBJ,GAAhB,CAAoB,CAApB,EAAsB,CAAtB,EAAwB,CAAxB;;AAEA,SAAIK,aAAa,0BAAehC,QAAf,EAAyBN,KAAzB,EAAgCE,MAAhC,CAAjB;;AAEA,MAAC,SAASqC,IAAT,GAAgB;AACb1B,kBAAS2B,MAAT;AACAlD,eAAMmD,KAAN;AACAb,uBAAcY,MAAd;AACA,aAAIjB,QAAQC,QAAR,KAAqB,gBAAzB,EAA2C;AACvClB,sBAASoC,MAAT,CAAgB1C,KAAhB,EAAuBE,MAAvB;AACH,UAFD,MAEO,IAAIqB,QAAQC,QAAR,KAAqB,cAAzB,EAAyC;AAC5Cc,wBAAWI,MAAX,CAAkBd,cAAce,MAAhC,EAAwCzD,KAAxC;AACH;AACDI,eAAMsD,GAAN;AACAC,+BAAsBN,IAAtB;AACH,MAXD;AAYH,EAzED,E;;;;;;AChBA;AACA,8C;;;;;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;AAGD;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa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A;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,QAAO;;AAEP,MAAK;AACL;AACA;;AAEA;;;AAGA,0BAAyB,oCAAoC;AAC7D;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;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CA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,YAAW;;AAEX,+DAA8D,uCAAuC;;AAErG;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;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E5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA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;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;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;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kBAAiB,eAAe,eAAe;AAC/C,kBAAiB,eAAe,eAAe;AAC/C,kBAAiB,eAAe,gBAAgB;AAChD,kBAAiB,eAAe,gBAAgB;;AAEhD;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;;AAGA,mBAAkB,eAAe;AACjC,mBAAkB,eAAe;AACjC,mBAAkB,eAAe;;AAEjC;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,qBAAoB,kBAAkB,kBAAkB;AACxD,qBAAoB,kBAAkB,kBAAkB;AACxD,sBAAqB,mBAAmB,oBAAoB;AAC5D,uBAAsB,oBAAoB,oBAAoB;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,cAAc,cAAc;AAC5C,iBAAgB,cAAc,cAAc;AAC5C,iBAAgB,cAAc,eAAe;AAC7C,iBAAgB,cAAc,eAAe;;AAE7C;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,kBAAiB,mBAAmB;AACpC,kBAAiB,mBAAmB;AACpC,kBAAiB,mBAAmB;;AAEpC,kBAAiB,oBAAoB;AACrC,kBAAiB,oBAAoB;AACrC,mBAAkB,qBAAqB;;AAEvC;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;;AAE9B;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,0CAAyC;;AAEzC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,gBAAe,aAAa,aAAa;AACzC,gBAAe,aAAa,aAAa;AACzC,gBAAe,aAAa,cAAc;AAC1C,gBAAe,aAAa,gBAAgB;;AAE5C;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,oBAAmB,aAAa,aAAa;AAC7C,gBAAe,iBAAiB,aAAa;AAC7C,gBAAe,aAAa,oBAAoB;AAChD,gBAAe,aAAa,cAAc;;AAE1C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,oBAAmB,QAAQ;;AAE3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,QAAQ;;AAE1B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,gCAA+B,eAAe;;AAE9C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mBAAkB,SAAS;AAC3B;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gCAA+B,8BAA8B;AAC7D,gCAA+B,8BAA8B;;AAE7D;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,iCAAgC,+BAA+B;AAC/D,iCAAgC,+BAA+B;AAC/D,iCAAgC,+BAA+B;;AAE/D;;AAEA;;AAEA;;AAEA,mCAAkC;AAClC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC,mCAAkC;AAClC,mCAAkC;;AAElC,gDAA+C;AAC/C,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA,iCAAgC,+BAA+B;AAC/D,iCAAgC,+BAA+B;;AAE/D;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mBAAkB,SAAS;;AAE3B;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mBAAkB,SAAS;;AAE3B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC,oCAAmC;AACnC,oCAAmC;;AAEnC,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,kCAAiC;;AAEjC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,kCAAiC;;AAEjC;;AAEA;;AAEA;;AAEA,iCAAgC;;AAEhC;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mCAAkC,SAAS;;AAE3C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,SAAQ,EAAE;;AAEV;AACA;;AAEA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA,mCAAkC,SAAS;;AAE3C;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mCAAkC,SAAS;;AAE3C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,qBAAqB;;AAExC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,iGAAgG;;AAEhG,kFAAiF;;AAEjF,0FAAyF;;AAEzF,iIAAgI,uDAAuD,6HAA6H,yHAAyH;;AAE7a,yEAAwE,iCAAiC;;AAEzG,4DAA2D;;AAE3D,iEAAgE;;AAEhE,4JAA2J,iCAAiC,kIAAkI,yGAAyG,yDAAyD,8FAA8F,eAAe,iBAAiB,GAAG,2DAA2D,wCAAwC,GAAG,uEAAuE,mEAAmE,6DAA6D,GAAG,yFAAyF,6BAA6B,iEAAiE,iEAAiE,6BAA6B,GAAG,mGAAmG,6BAA6B,iEAAiE,iEAAiE,yCAAyC,GAAG,6DAA6D,6BAA6B,qDAAqD,8CAA8C,GAAG,6JAA6J,oCAAoC,2EAA2E,8EAA8E,uEAAuE,8DAA8D,sEAAsE,+CAA+C,2DAA2D,oCAAoC,yBAAyB,GAAG,yFAAyF,iCAAiC,sDAAsD,yCAAyC,6BAA6B,8BAA8B,+BAA+B,sCAAsC,gGAAgG,mCAAmC,cAAc,GAAG,wDAAwD,mBAAmB,oCAAoC,oCAAoC,oCAAoC,oCAAoC,UAAU,wBAAwB,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,mBAAmB,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,KAAK,2BAA2B,YAAY,kBAAkB,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,kBAAkB,kBAAkB,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,KAAK,mCAAmC,mCAAmC,GAAG,0DAA0D,mCAAmC,mCAAmC,uFAAuF,eAAe,GAAG,uHAAuH,iDAAiD,iDAAiD,iDAAiD,iDAAiD,GAAG,2HAA2H,6BAA6B,8BAA8B,+BAA+B,gBAAgB,wCAAwC,0BAA0B,mEAAmE,wBAAwB,4DAA4D,4DAA4D,4DAA4D,4DAA4D,UAAU,sCAAsC,8CAA8C,iDAAiD,iDAAiD,iDAAiD,iDAAiD,iDAAiD,oBAAoB,0EAA0E,0EAA0E,0EAA0E,2FAA2F,2FAA2F,0BAA0B,sCAAsC,gBAAgB,GAAG,4QAA4Q,uBAAuB,4EAA4E,sDAAsD,gCAAgC,kDAAkD,gCAAgC,oDAAoD,0HAA0H,kGAAkG,yCAAyC,+BAA+B,GAAG,iLAAiL,uBAAuB,4EAA4E,kCAAkC,+FAA+F,8BAA8B,GAAG,mIAAmI,uEAAuE,0DAA0D,oDAAoD,iCAAiC,sEAAsE,gDAAgD,uCAAuC,GAAG,kCAAkC,gBAAgB,GAAG,wEAAwE,+EAA+E,GAAG,oKAAoK,2EAA2E,8DAA8D,sEAAsE,+CAA+C,uCAAuC,+CAA+C,yBAAyB,GAAG,oEAAoE,yDAAyD,GAAG,qEAAqE,iDAAiD,GAAG;;AAEtnT,+EAA8E,4BAA4B,sBAAsB,+BAA+B,+BAA+B,0DAA0D,wEAAwE,wEAAwE,8BAA8B,KAAK,wEAAwE,sCAAsC,sCAAsC,0BAA0B,qCAAqC,qCAAqC,sCAAsC,kEAAkE,0DAA0D,KAAK;;AAE10B,iFAAgF,2BAA2B,SAAS,uCAAuC,+DAA+D,KAAK,mFAAmF,0CAA0C,yBAAyB,SAAS,yCAAyC,2EAA2E,OAAO,6BAA6B;;AAEthB,sJAAqJ,iEAAiE;;AAEtN,8IAA6I;;AAE7I,+IAA8I;;AAE9I,uEAAsE;;AAEtE,qEAAoE;;AAEpE,mEAAkE;;AAElE,iEAAgE;;AAEhE,yVAAwV,YAAY,EAAE,kCAAkC,cAAc,EAAE,kCAAkC,gBAAgB,cAAc,EAAE,wCAAwC,qCAAqC,EAAE,wCAAwC,8DAA8D,mEAAmE,8BAA8B,GAAG,wBAAwB,eAAe,mBAAmB,iBAAiB,IAAI,yBAAyB,uBAAuB,wBAAwB,yBAAyB,0BAA0B,IAAI,2BAA2B,kBAAkB,gBAAgB,iBAAiB,IAAI,0DAA0D,0DAA0D,GAAG,iEAAiE,0DAA0D,GAAG,kFAAkF,8DAA8D,4CAA4C,GAAG,iFAAiF,4DAA4D,GAAG,oHAAoH,gIAAgI,GAAG,qCAAqC,aAAa,0CAA0C,0CAA0C,0CAA0C,eAAe,GAAG;;AAEhhE,gJAA+I,uCAAuC,kBAAkB,2CAA2C,mFAAmF,mDAAmD,KAAK,UAAU,mFAAmF,mDAAmD,KAAK,gBAAgB,GAAG,6LAA6L,yDAAyD,wCAAwC,wCAAwC,gDAAgD,gDAAgD,kDAAkD,yCAAyC,mCAAmC,kDAAkD,GAAG,iMAAiM,uEAAuE,2CAA2C,gEAAgE,qDAAqD,mDAAmD,+DAA+D,yEAAyE,gCAAgC,6CAA6C,WAAW,gBAAgB,+CAA+C,uCAAuC,oBAAoB,uDAAuD,sDAAsD,2DAA2D,KAAK,yBAAyB,sDAAsD,yDAAyD,2DAA2D,KAAK,yBAAyB,sDAAsD,6DAA6D,2DAA2D,KAAK,yBAAyB,sDAAsD,qDAAqD,6DAA6D,KAAK,yBAAyB,uDAAuD,wDAAwD,6DAA6D,KAAK,UAAU,uDAAuD,4DAA4D,6DAA6D,KAAK,qBAAqB,oDAAoD,uDAAuD,6CAA6C,oDAAoD,GAAG,gIAAgI,oDAAoD,mCAAmC,wBAAwB,kCAAkC,mEAAmE,wBAAwB,6BAA6B,gCAAgC,yCAAyC,2CAA2C,2DAA2D,iEAAiE,2DAA2D,iEAAiE,2CAA2C,iCAAiC,GAAG;;AAE5mI,gFAA+E,+DAA+D;;AAE9I,qGAAoG,oCAAoC,mCAAmC;;AAE3K,oKAAmK;;AAEnK,2GAA0G,sEAAsE,+CAA+C;;AAE/N,2FAA0F;;AAE1F,iFAAgF;;AAEhF,yEAAwE,iBAAiB,GAAG,6DAA6D,kEAAkE,GAAG,6DAA6D,wEAAwE,GAAG,sCAAsC,sLAAsL,GAAG,sCAAsC,uKAAuK,GAAG,sCAAsC,oEAAoE,GAAG,sCAAsC,iEAAiE,sEAAsE,sEAAsE,GAAG,yDAAyD,uDAAuD,GAAG,yDAAyD,2DAA2D,wDAAwD,6CAA6C,mDAAmD,GAAG,yDAAyD,uEAAuE,GAAG,yDAAyD,2DAA2D,iDAAiD,kDAAkD,+DAA+D,GAAG,uGAAuG,yCAAyC,0CAA0C,uDAAuD,iBAAiB,4CAA4C,+CAA+C,0BAA0B,4DAA4D,mBAAmB,GAAG,mHAAmH,wCAAwC,yCAAyC,mBAAmB,2CAA2C,wCAAwC,wCAAwC,gDAAgD,uCAAuC,GAAG;;AAE3wF,iMAAgM,yEAAyE,oGAAoG,6FAA6F,sDAAsD,gJAAgJ,4DAA4D,qEAAqE,uGAAuG,oDAAoD,+JAA+J,sEAAsE,2CAA2C,yDAAyD,6IAA6I,kIAAkI,8GAA8G;;AAElnD,6GAA4G,kCAAkC,wKAAwK,sEAAsE,wCAAwC,uCAAuC,yIAAyI,qCAAqC;;AAEznB,6JAA4J,qCAAqC,oCAAoC;;AAErO,+JAA8J,qFAAqF,oFAAoF,6FAA6F,sFAAsF;;AAE1f,+DAA8D;;AAE9D,kEAAiE;;AAEjE,iKAAgK,yEAAyE,8EAA8E;;AAEvT,mEAAkE,2BAA2B,kDAAkD,qCAAqC,2BAA2B;;AAE/M,gFAA+E,oEAAoE,kDAAkD,kDAAkD,+EAA+E,wEAAwE,iBAAiB;;AAE/Z,6IAA4I;;AAE5I,kFAAiF,oCAAoC;;AAErH,0DAAyD,4BAA4B,qCAAqC,mDAAmD,kDAAkD,gCAAgC,4CAA4C,yCAAyC,0CAA0C,4BAA4B,kDAAkD,oCAAoC,cAAc,gCAAgC,8CAA8C,sBAAsB,SAAS,+EAA+E,4DAA4D,wDAAwD,kEAAkE,6FAA6F,iBAAiB,qDAAqD,qBAAqB,SAAS,6EAA6E,4DAA4D,wDAAwD,kEAAkE,6FAA6F,iBAAiB,oDAAoD,oBAAoB,SAAS,2FAA2F,4DAA4D,wDAAwD,kEAAkE,6FAA6F,iBAAiB,qDAAqD,qBAAqB,SAAS,qFAAqF,mHAAmH,iBAAiB;;AAE9pE,oDAAmD,qEAAqE,wCAAwC,4DAA4D,gCAAgC,GAAG,qDAAqD,qBAAqB,iBAAiB,iBAAiB,uBAAuB,yBAAyB,yBAAyB,MAAM,iEAAiE,+JAA+J,iDAAiD,yDAAyD,iCAAiC,KAAK,yDAAyD,oBAAoB,iBAAiB,qBAAqB,kBAAkB,iBAAiB,uBAAuB,yBAAyB,yBAAyB,MAAM,uDAAuD,6IAA6I,6DAA6D,mDAAmD,8CAA8C,2CAA2C,4HAA4H,iEAAiE,KAAK,uDAAuD,oBAAoB,qBAAqB,iBAAiB,qBAAqB,kBAAkB,oBAAoB,wBAAwB,iBAAiB,uBAAuB,yBAAyB,yBAAyB,MAAM,oDAAoD,2IAA2I,4DAA4D,mDAAmD,8CAA8C,yEAAyE,2CAA2C,4FAA4F,4CAA4C,yIAAyI,mCAAmC,OAAO,OAAO,wCAAwC,oCAAoC,OAAO,KAAK,gEAAgE,iBAAiB,oBAAoB,qBAAqB,sBAAsB,MAAM,6BAA6B,2BAA2B,iEAAiE,6DAA6D,qBAAqB,oBAAoB,uBAAuB,MAAM,gEAAgE,iHAAiH,gEAAgE,kDAAkD,4FAA4F,gEAAgE,oCAAoC,KAAK,oKAAoK,kFAAkF,wGAAwG,uHAAuH,gGAAgG,+EAA+E,qHAAqH,0DAA0D,kDAAkD,gEAAgE,KAAK,kGAAkG,qDAAqD,+GAA+G,8DAA8D,KAAK,+IAA+I,2GAA2G,oGAAoG,mFAAmF,0FAA0F,6GAA6G,0HAA0H,mGAAmG,+EAA+E,0HAA0H,+GAA+G,gEAAgE,0DAA0D,+EAA+E,iHAAiH,0FAA0F,+EAA+E,oJAAoJ,mIAAmI,4GAA4G,+EAA+E,2DAA2D,KAAK;;AAE39N,2DAA0D,2CAA2C,oCAAoC,yCAAyC,+CAA+C;;AAEjO,+DAA8D,8CAA8C,qCAAqC,uBAAuB,wBAAwB,6BAA6B,4BAA4B,IAAI,6NAA6N,gDAAgD,iDAAiD,8CAA8C,kFAAkF,6MAA6M,+JAA+J,8EAA8E,8EAA8E,KAAK,0LAA0L,2HAA2H,uFAAuF,kDAAkD,sEAAsE,yGAAyG,oLAAoL,GAAG,iLAAiL,iGAAiG,GAAG;;AAEjwE,4DAA2D,uEAAuE,mEAAmE,6HAA6H,0IAA0I,+CAA+C,uEAAuE;;AAElkB,gEAA+D,uBAAuB,6BAA6B,wBAAwB,0CAA0C,+BAA+B,cAAc,oKAAoK,6IAA6I,GAAG,yNAAyN,gDAAgD,iDAAiD,8CAA8C,mDAAmD,6MAA6M,+JAA+J,wEAAwE,wEAAwE,KAAK,sLAAsL,4EAA4E,gDAAgD,4DAA4D,uIAAuI,wCAAwC,oLAAoL,wHAAwH,2MAA2M,aAAa,6KAA6K,iGAAiG,GAAG,6MAA6M,6FAA6F,0BAA0B,yGAAyG,wCAAwC,mLAAmL,mNAAmN,aAAa,kkBAAkkB,kHAAkH,GAAG;;AAEnwI,qDAAoD,sCAAsC,2BAA2B,gDAAgD,4BAA4B,gFAAgF,oBAAoB,sBAAsB,SAAS,oCAAoC,yEAAyE,4PAA4P,+EAA+E,KAAK,qFAAqF,oBAAoB,qBAAqB,SAAS,kCAAkC,uEAAuE,iPAAiP,+EAA+E,KAAK,kGAAkG,oBAAoB,oBAAoB,SAAS,gDAAgD,qFAAqF,2RAA2R,+EAA+E,KAAK,2GAA2G,oBAAoB,0BAA0B,SAAS,0CAA0C,8EAA8E,KAAK,gHAAgH,2GAA2G,wEAAwE,mDAAmD,+DAA+D,qBAAqB,SAAS,sFAAsF,OAAO,mKAAmK,mFAAmF,mLAAmL,uJAAuJ,oDAAoD,qGAAqG;;AAEr8G,uJAAsJ;;AAEtJ,yFAAwF,6DAA6D;;AAErJ,oHAAmH,0CAA0C;;AAE7J,gIAA+H,qEAAqE,qEAAqE;;AAEzQ,gFAA+E,gDAAgD,+BAA+B;;AAE9J,mEAAkE;;AAElE,sKAAqK,iDAAiD;;AAEtN,gFAA+E,0BAA0B;;AAEzG,iEAAgE,kFAAkF,wCAAwC;;AAE1L,8FAA6F;;AAE7F,8HAA6H,2EAA2E,2EAA2E,2EAA2E;;AAE9V,iIAAgI,sDAAsD;;AAEtL,+HAA8H,4EAA4E,4EAA4E,4EAA4E,wGAAwG,4EAA4E,4EAA4E,4EAA4E;;AAE9qB,uGAAsG,kCAAkC;;AAExI,4IAA2I,iGAAiG,iDAAiD,2DAA2D,uFAAuF,mGAAmG;;AAElhB,qFAAoF,6BAA6B,4DAA4D,oCAAoC,oCAAoC,gCAAgC,gCAAgC,oDAAoD,qDAAqD,sCAAsC,8DAA8D,sCAAsC,iCAAiC,qCAAqC,KAAK;;AAEnnB,+DAA8D,2CAA2C,GAAG,+CAA+C,+BAA+B,GAAG,wCAAwC,0CAA0C,0EAA0E,uEAAuE,sCAAsC,4CAA4C,iDAAiD,iCAAiC,yBAAyB,GAAG,8CAA8C,mCAAmC,GAAG,mGAAmG,6CAA6C,GAAG,yGAAyG,+CAA+C,GAAG,kGAAkG,iEAAiE,GAAG,qGAAqG,gEAAgE,GAAG;;AAEhzC,uGAAsG;;AAEtG,2FAA0F,wEAAwE,sDAAsD;;AAExN,iEAAgE,kFAAkF,wCAAwC;;AAE1L,8FAA6F;;AAE7F,8IAA6I,6DAA6D,8FAA8F,uDAAuD,iGAAiG,yDAAyD,kFAAkF,2EAA2E,KAAK,sFAAsF,2CAA2C,0CAA0C,wDAAwD,yFAAyF,yFAAyF,yFAAyF,yFAAyF,wCAAwC,mCAAmC,mCAAmC,iCAAiC,eAAe,KAAK,wHAAwH,uCAAuC,kCAAkC,4HAA4H,2CAA2C,sEAAsE,+CAA+C,0BAA0B,4FAA4F,iDAAiD,iDAAiD,iDAAiD,iDAAiD,w0BAAw0B,mGAAmG,iDAAiD,iDAAiD,iDAAiD,iDAAiD,0+BAA0+B,uFAAuF,mBAAmB,iBAAiB,KAAK,+CAA+C,2BAA2B,qEAAqE,0BAA0B,oDAAoD,yBAAyB,4CAA4C,2CAA2C,kCAAkC,uDAAuD,OAAO,kCAAkC,kCAAkC,6CAA6C,OAAO,kCAAkC,kCAAkC,2CAA2C,qCAAqC,OAAO,gEAAgE,KAAK,6HAA6H,0EAA0E,6CAA6C,+CAA+C,qEAAqE,+IAA+I,4zBAA4zB,2FAA2F,iBAAiB;;AAEzhN,0IAAyI,6DAA6D,4FAA4F,uDAAuD,+FAA+F,yDAAyD;;AAEjf,4FAA2F,oBAAoB,SAAS,kFAAkF,KAAK,yDAAyD,qBAAqB,SAAS,oEAAoE,KAAK,0DAA0D,sBAAsB,SAAS,sEAAsE,KAAK;;AAEnhB,yDAAwD,uBAAuB,wFAAwF,oBAAoB,oBAAoB,SAAS,gDAAgD,yNAAyN,KAAK,6DAA6D,oBAAoB,qBAAqB,SAAS,kCAAkC,+KAA+K,KAAK,gEAAgE,oBAAoB,sBAAsB,SAAS,oCAAoC,0LAA0L,KAAK,sCAAsC,GAAG;;AAE1qC,6FAA4F,iDAAiD,iDAAiD,iDAAiD;;AAE/O,6EAA4E,mCAAmC,2DAA2D,mCAAmC,oCAAoC,8CAA8C,0BAA0B,sDAAsD,yDAAyD,mDAAmD,oDAAoD,6BAA6B,wEAAwE,wEAAwE,wEAAwE,wEAAwE,2CAA2C,oBAAoB,OAAO,sDAAsD,8CAA8C,2CAA2C,oBAAoB,OAAO;;AAE5jC,wGAAuG,+BAA+B,oDAAoD,oDAAoD,oDAAoD,oDAAoD,2CAA2C;;AAEjY,gFAA+E,0CAA0C,0CAA0C,0CAA0C,0CAA0C,8DAA8D,sEAAsE;;AAE3X,qDAAoD,+EAA+E,uCAAuC,kCAAkC;;AAE5M,2FAA0F;;AAE1F,gHAA+G;;AAE/G,+GAA8G,sCAAsC,wCAAwC,uCAAuC,GAAG,0CAA0C,iCAAiC,uDAAuD,GAAG,8MAA8M,iCAAiC,qGAAqG,GAAG,iDAAiD,iCAAiC,8CAA8C,4GAA4G,GAAG;;AAEj7B,gRAA+Q;;AAE/Q,8QAA6Q,8BAA8B;;AAE3S,qSAAoS;;AAEpS,oGAAmG;;AAEnG,mGAAkG,sBAAsB;;AAExH,sFAAqF;;AAErF,wNAAuN,2EAA2E;;AAElS,6CAA4C,sBAAsB,wBAAwB,8BAA8B,kCAAkC,6FAA6F,8BAA8B,GAAG;;AAExR,+CAA8C,kCAAkC,iEAAiE,2DAA2D;;AAE5M,uEAAsE,4OAA4O,2EAA2E,4DAA4D,mOAAmO,sFAAsF,aAAa;;AAE/vB,wQAAuQ,2RAA2R;;AAEliB,iDAAgD,8BAA8B,iGAAiG,kIAAkI,GAAG;;AAEpT,uDAAsD,+IAA+I,2PAA2P,GAAG;;AAEnc,mDAAkD,sBAAsB,8BAA8B,kCAAkC,iDAAiD,kBAAkB,8DAA8D,yEAAyE,oDAAoD,GAAG;;AAEzY,mDAAkD,kCAAkC,iEAAiE,2DAA2D;;AAEhN,8CAA6C,wBAAwB,yBAAyB,0BAA0B,8BAA8B,gLAAgL,8FAA8F,cAAc,KAAK,qCAAqC,iDAAiD,qGAAqG,yDAAyD,6IAA6I;;AAExzB,6CAA4C,+BAA+B,8BAA8B,wKAAwK,oEAAoE,8DAA8D,gDAAgD,kGAAkG;;AAEriB,6CAA4C,wBAAwB,8CAA8C,8bAA8b,wFAAwF,wSAAwS,mHAAmH,6DAA6D,8FAA8F,wDAAwD,iHAAiH,6IAA6I;;AAEp/C,yVAAwV,iiBAAiiB;;AAEz3B,+CAA8C,wBAAwB,wBAAwB,2BAA2B,iDAAiD,2mBAA2mB,wFAAwF,yGAAyG,0CAA0C,sTAAsT,+GAA+G,0GAA0G,0DAA0D,yGAAyG,4IAA4I,iHAAiH,6IAA6I;;AAE5jE,oEAAmE,iDAAiD,uZAAuZ,qkBAAqkB;;AAEhlC,4DAA2D,wBAAwB,wBAAwB,0BAA0B,wBAAwB,itBAAitB,wFAAwF,yGAAyG,0CAA0C,0iBAA0iB,uFAAuF,6IAA6I;;AAEv2D,kEAAiE,8CAA8C,qZAAqZ,iTAAiT,+QAA+Q,qHAAqH;;AAEzrC,kEAAiE,wBAAwB,0BAA0B,0BAA0B,wBAAwB,8CAA8C,qCAAqC,qCAAqC,8CAA8C,swBAAswB,wFAAwF,yGAAyG,0CAA0C,qnBAAqnB,yDAAyD,6IAA6I;;AAEvnE,wEAAuE,8CAA8C,4ZAA4Z,iTAAiT,+QAA+Q,yFAAyF;;AAE1qC,2DAA0D,iHAAiH,sDAAsD,oLAAoL,yJAAyJ,GAAG;;AAEjjB,oJAAmJ,sDAAsD,mMAAmM,6PAA6P,4TAA4T,WAAW;;AAEh9B,0CAAyC,wBAAwB,+QAA+Q,4EAA4E,iDAAiD,0KAA0K,yDAAyD,6IAA6I;;AAE7zB,wCAAuC,sBAAsB,0MAA0M,wKAAwK,mCAAmC,yKAAyK;;AAE3nB,2CAA0C,yKAAyK,8EAA8E,GAAG;;AAEpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA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AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,OAAO;;AAE1B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,oBAAmB,OAAO;;AAE1B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;;AAGH;;AAEA;;AAEA,oBAAmB,OAAO;;AAE1B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,mBAAkB,iCAAiC;;AAEnD;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,+CAA8C,QAAQ;;AAEtD;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA,kBAAiB;;AAEjB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,wBAAuB,kBAAkB;;AAEzC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,+CAA8C,QAAQ;;AAEtD;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,4CAA2C,QAAQ;;AAEnD;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,SAAQ;;AAER;;AAEA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;;;AAIH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,uBAAuB;;AAE7D;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,qBAAoB,sBAAsB;;AAE1C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,4BAA2B,gBAAgB;;AAE3C;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,qBAAoB,sBAAsB;;AAE1C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,4BAA2B,kBAAkB;;AAE7C;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,8CAA6C,OAAO;;AAEpD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH,0BAAyB;;AAEzB;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,oBAAmB;AACnB,mBAAkB;AAClB,kBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,0BAA0B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,qBAAoB,4BAA4B;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA,qBAAoB,qBAAqB;;AAEzC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,sDAAqD,QAAQ;;AAE7D;;AAEA;;AAEA,qDAAoD,QAAQ;;AAE5D;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,uBAAsB;;AAEtB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,uCAAsC,OAAO;;AAE7C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,oBAAmB,kBAAkB;;AAErC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,wBAAwB;;AAE5C;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,wBAAwB;;AAE5C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,oBAAmB,kBAAkB;;AAErC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,wBAAwB;;AAE5C;;AAEA;;AAEA;;AAEA,qBAAoB,wBAAwB;;AAE5C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8BAA6B,gBAAgB;;AAE7C;;AAEA,uCAAsC,2BAA2B;;AAEjE;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,+CAA8C,QAAQ;;AAEtD;AACA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;AACA;;AAEA,qDAAoD,QAAQ;;AAE5D;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,2BAA0B,sBAAsB;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,sBAAqB,mBAAmB;;AAExC;;AAEA;AACA;;AAEA,+CAA8C,QAAQ;;AAEtD;;AAEA;;AAEA;;AAEA,MAAK;;AAEL,sBAAqB,oBAAoB;;AAEzC;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ,qBAAoB,0BAA0B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,2CAA0C,QAAQ;;AAElD;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2CAA0C,QAAQ;;AAElD;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,iDAAgD,QAAQ;;AAExD;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,+CAA8C,QAAQ;;AAEtD;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,0CAAyC,QAAQ;;AAEjD;AACA,wBAAuB;;AAEvB;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,0CAAyC,QAAQ;;AAEjD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,2CAA0C,QAAQ;;AAElD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;;AAEA;;AAEA,oCAAmC,QAAQ;;AAE3C;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,oDAAmD,QAAQ;;AAE3D;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mDAAkD,QAAQ;;AAE1D;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kCAAiC,QAAQ;;AAEzC;;AAEA;;AAEA;;AAEA;;AAEA,qCAAoC,QAAQ;;AAE5C;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;;AAEA,yBAAwB;AACxB;;AAEA;AACA,4BAA2B;AAC3B;AACA;AACA;;AAEA,2CAA0C,QAAQ;;AAElD;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;;AAGA;AACA;AACA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,qBAAoB,OAAO;;AAE3B;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,6CAA4C,QAAQ;;AAEpD;;AAEA;;AAEA,iDAAgD,QAAQ;;AAExD;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,oBAAmB,YAAY;;AAE/B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,oBAAmB,YAAY;;AAE/B;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,0BAA0B;;AAE7C;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,uBAAuB;;AAE1C;;AAEA;AACA,2BAA0B;AAC1B;AACA;AACA;AACA;AACA;;AAEA;;AAEA,yCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,kDAAiD;AACjD;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC,QAAQ;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA,oCAAmC,QAAQ;;AAE3C;;AAEA;;AAEA;;AAEA;;AAEA,mCAAkC,QAAQ;;AAE1C;;AAEA;;AAEA;;AAEA,kDAAiD,QAAQ;;AAEzD;;AAEA;;AAEA;;AAEA;;AAEA,4CAA2C,QAAQ;;AAEnD;;AAEA,mCAAkC,QAAQ;;AAE1C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,0CAAyC,QAAQ;;AAEjD;AACA;;AAEA;;AAEA;;AAEA;;AAEA,0DAAyD,QAAQ;;AAEjE;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yDAAwD,QAAQ;;AAEhE;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,0CAAyC,QAAQ;;AAEjD;;AAEA;;AAEA;;AAEA;;AAEA,+DAA8D,QAAQ;;AAEtE;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,6DAA4D,QAAQ;;AAEpE;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA,2CAA0C,QAAQ;;AAElD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,uCAAsC,2BAA2B;;AAEjE;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,qBAAoB;;AAEpB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,8CAA6C,OAAO;;AAEpD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KA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CA;;AAEA;AACA;;AAEA,uBAAsB;AACtB,uBAAsB;;AAEtB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;AACA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AAC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AEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB;AACpB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,8BAA8B;;AAEjD;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;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EA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,oEAAmE;;AAEnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AA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EA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gBAAe,sBAAsB;;AAErC;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gB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EA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;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CA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 3aae6504ba570c47e9d2","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
\\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
\\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
\\n \\n
\\n\\n
\",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nimport {PROXY_BUFFER_SIZE} from './proxy_geometry'\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n var composer = new EffectComposer(renderer);\r\n var shaderPass = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/rayMarch-frag.glsl')\r\n \r\n });\r\n shaderPass.renderToScreen = true;\r\n composer.addPass(shaderPass);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n composer.render();\r\n // console.log(composer);\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\n#define MAX_GEOMETRY_COUNT 100\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 20.0\\r\\n\\r\\n/* This is how I'm packing the data\\r\\nstruct geometry_t {\\r\\n vec3 position;\\r\\n float type;\\r\\n};\\r\\n*/\\r\\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\\r\\n// uniform int u_count;\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\nvec4 resColor;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t *****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\n//diagonal is the vector from the center of the box to the first quadrant corner\\r\\nfloat boxSDF(vec3 point, vec3 diagonal) {\\r\\n\\tvec3 d = abs(point) - diagonal;\\r\\n \\treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\\r\\n}\\r\\n\\r\\nfloat SDF_Mandlebulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i=0; i<4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n resColor = trap;\\r\\n\\r\\n return 0.25*log(m)*sqrt(m)/dz;\\r\\n}\\r\\n\\r\\n//Operators:\\r\\n\\r\\nfloat intersection(float d1, float d2)\\r\\n{\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 )\\r\\n{\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2)\\r\\n{\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n//returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform(vec3 point, mat4 trans)\\r\\n{\\r\\n\\t//columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\n// Return the distance of the closest object in the scene\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\treturn SDF_Sphere( pos, 1.0 );\\r\\n}\\r\\n\\r\\nfloat sceneMap2( vec3 pos ){\\r\\n\\r\\n\\tfloat angle = u_time/(2.0*3.1415);\\r\\n\\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\\r\\n\\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\\r\\n\\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\\r\\n\\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\\r\\n\\r\\n\\tmat4 northMat = mat4(1.0); \\r\\n\\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 southMat = mat4(1.0); \\r\\n\\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 westMat = mat4(1.0); \\r\\n\\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\\r\\n\\tmat4 eastMat = mat4(1.0); \\r\\n\\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\\r\\n\\r\\n\\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\\r\\n\\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\\r\\n\\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\\r\\n\\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\\r\\n\\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\\r\\n\\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\\r\\n\\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\\r\\n\\t\\r\\n\\t// float dist1;\\r\\n\\t// float bb1 = boxSDF(newPos1, vec3(1.5,1.5,1.5));\\r\\n\\t// if(bb1 < .015)\\r\\n\\t// {\\r\\n\\t// \\tfloat power = 10.0;//12.0 + abs(sin(u_time/4.0))*40.0;\\r\\n\\t// \\tdist1 = SDF_Mandlebulb(newPos1, power);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist1 = bb1;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist2;\\r\\n\\t// float bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1));\\r\\n\\t// if(bb2 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist2 = SDF_Mandlebulb(newPos2, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist2 = bb2;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist3;\\r\\n\\t// float bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t// if(bb3 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist3 = SDF_Mandlebulb(newPos3, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist3 = bb3;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist4;\\r\\n\\t// float bb4 = boxSDF(newPos4, vec3(1.1,1.1,1.1));\\r\\n\\t// if(bb4 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist4 = SDF_Mandlebulb(newPos4, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist4 = bb4;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist5;\\r\\n\\t// float bb5 = boxSDF(newPos5, vec3(1.1,1.1,1.1));\\r\\n\\t// if(bb5 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist5 = SDF_Mandlebulb(newPos5, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist5 = bb5;\\r\\n\\t// }\\r\\n\\r\\n\\t//float man2 = SDF_Mandlebulb(newPos2, 16.0);\\r\\n\\t//float man3 = SDF_Mandlebulb(newPos3, 16.0);\\r\\n\\t//float man4 = SDF_Mandlebulb(newPos4, 16.0);\\r\\n\\t//float man5 = SDF_Mandlebulb(newPos5, 16.0);\\r\\n\\t//float man6 = SDF_Mandlebulb(newPos6, 24.0);\\r\\n\\t//float man7 = SDF_Mandlebulb(newPos7, 24.0);\\r\\n\\t//float man8 = SDF_Mandlebulb(newPos8, 24.0);\\r\\n\\t//float man9 = SDF_Mandlebulb(newPos9, 24.0);\\r\\n\\t\\r\\n\\t//return un(dist1, un(dist2, un(dist3, un(dist4, dist5))));\\r\\n\\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\\r\\n\\r\\n\\tfloat dist1;\\r\\n\\tvec3 newPos1 = transform(transform(pos + vec3(cos((u_time+4.0)/8.0)*4.0, 0, sin(u_time/7.0)*3.5), cwMat), northMat);\\t\\r\\n\\tfloat bb1 = boxSDF(newPos1, vec3(1.1,1.1,1.1));\\r\\n\\tif(bb1 < .015)\\r\\n\\t{\\r\\n\\t\\tfloat power = 12.0;\\r\\n\\t\\tdist1 = SDF_Mandlebulb(newPos1, power);\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdist1 = bb1;\\r\\n\\t}\\r\\n\\r\\n\\tfloat dist2;\\r\\n\\tvec3 newPos2 = transform(transform(pos + vec3(cos((u_time+50.0)/10.0)*2.0, 1, sin((u_time+30.0)/6.0)*2.5), ccwMat), eastMat);\\r\\n\\tfloat bb2 = boxSDF(newPos2, vec3(1.1,1.1,1.1));\\r\\n\\tif(bb2 < .015)\\r\\n\\t{\\r\\n\\t\\t\\r\\n\\t\\tfloat power = 12.0;\\r\\n\\t\\tdist2 = SDF_Mandlebulb(newPos2, power);\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdist2 = bb2;\\r\\n\\t}\\r\\n\\r\\n\\tfloat dist3;\\r\\n\\tvec3 newPos3 = transform(transform(pos + vec3(sin((u_time)/16.0)*3.0, -1, cos((u_time+75.0)/3.0)*2.0), cwMat), westMat);\\r\\n\\tfloat bb3 = boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\tif(bb3 < .015)\\r\\n\\t{\\r\\n\\t\\t\\r\\n\\t\\tfloat power = 12.0;\\r\\n\\t\\tdist3 = SDF_Mandlebulb(newPos3, power);\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdist3 = bb3;\\r\\n\\t}\\r\\n\\r\\n\\treturn un(dist1, un(dist2, dist3));\\r\\n\\r\\n\\t// float dist4;\\r\\n\\t// float bb4 = boxSDF(newPos4, vec3(1.2,1.2,1.2));\\r\\n\\t// if(bb4 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist4 = SDF_Mandlebulb(newPos4, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist4 = bb4;\\r\\n\\t// }\\r\\n\\r\\n\\t// float dist5;\\r\\n\\t// float bb5 = boxSDF(newPos5, vec3(1.2,1.2,1.2));\\r\\n\\t// if(bb5 < .015)\\r\\n\\t// {\\r\\n\\t// \\tdist5 = SDF_Mandlebulb(newPos5, 16.0);\\r\\n\\t// }\\r\\n\\t// else\\r\\n\\t// {\\r\\n\\t// \\tdist5 = bb5;\\r\\n\\t// }\\r\\n\\t\\r\\n\\t//float man2 = SDF_Mandlebulb(newPos2, 16.0);\\r\\n\\t//float man3 = SDF_Mandlebulb(newPos3, 16.0);\\r\\n\\t//float man4 = SDF_Mandlebulb(newPos4, 16.0);\\r\\n\\t//float man5 = SDF_Mandlebulb(newPos5, 16.0);\\r\\n\\t//float man6 = SDF_Mandlebulb(newPos6, 24.0);\\r\\n\\t//float man7 = SDF_Mandlebulb(newPos7, 24.0);\\r\\n\\t//float man8 = SDF_Mandlebulb(newPos8, 24.0);\\r\\n\\t//float man9 = SDF_Mandlebulb(newPos9, 24.0);\\r\\n\\t// return un(dist1, un(dist2, un(dist3, un(dist4, dist5))));\\r\\n\\t\\r\\n\\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\\r\\n\\t//return dist1;\\r\\n\\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\nvec3 computeNormal( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Check for intersection with the scene for increasing t-values\\r\\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\tfloat dist;\\r\\n\\tfloat t = 0.01;\\r\\n\\tfor(int i = 0; i < 500; i++) {\\r\\n\\t\\tfloat dist = sceneMap2(origin + t * direction);\\r\\n\\t\\tif(dist < 0.0001) {\\r\\n\\t\\t\\treturn vec2(t, 1.0); // intersection\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn vec2(0.0, -1.0); // no intersection\\r\\n}\\r\\n\\r\\n\\r\\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\\r\\n\\tfloat dot = dot(normalize(toCam + toLight), normal);\\r\\n\\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\\r\\n}\\r\\n\\r\\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\\r\\nfloat ComputeAO( vec3 pos, vec3 normal ) {\\r\\n\\tfloat tStep = 0.0025;\\r\\n\\tfloat t = 0.0;\\r\\n\\tfloat ao = 1.0;\\r\\n\\tfloat diff = 0.0;\\r\\n\\tfloat k = 72.0;\\r\\n\\tfor(int i = 0; i < 5; i++) {\\r\\n\\t\\tvec3 sample = pos + t * normal;\\r\\n\\t\\tfloat dist = sceneMap2( sample );\\r\\n\\t\\tdiff += pow(0.5, float (i)) * (t - dist);\\r\\n\\t\\tt += tStep;\\r\\n\\t}\\r\\n\\tao -= clamp(k * diff, 0.0, 1.0);\\r\\n\\treturn ao;\\r\\n}\\r\\n\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n\\t\\r\\n\\t/** Raycasting **/\\r\\n\\t\\r\\n\\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\\r\\n\\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t\\t\\t\\tgl_FragCoord.y / u_resolution.y) - 1.0;\\r\\n\\r\\n\\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\\r\\n\\t//vec3 cameraPos = vec3(1, -4, 2);\\r\\n\\t//vec3 cameraPos = vec3(1, 0, 1);\\r\\n\\t\\r\\n\\t// Circle the origin (0, 0, 0)\\r\\n\\t// cameraPos.x = sin(u_time) * 10.0;\\r\\n\\t// cameraPos.z = cos(u_time) * 10.0;\\r\\n\\t\\r\\n\\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\\r\\n\\t\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos);\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\\r\\n\\t\\r\\n\\t// Perform the raymarch\\r\\n\\tvec3 direction = normalize(point_World - cameraPos);\\r\\n\\tvec2 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\t/** Shading and lighting **/\\r\\n\\t\\r\\n\\tif(isect.y > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormal( isectPos );\\r\\n\\t\\t\\r\\n\\t\\t// Lighting\\r\\n\\t\\tvec3 baseMaterial = vec3(0.2, 0.2, 0.2);\\r\\n\\t\\tvec3 trapColor = vec3(resColor.x+(sin((u_time+isectPos.x)/2.0)*0.2), resColor.y-(cos((u_time+isectPos.y)/8.0)*0.5), resColor.z+(cos((u_time-isectPos.z)/2.0)*0.8));\\r\\n\\t\\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\\r\\n\\t\\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\\r\\n\\t\\t\\r\\n\\t\\tvec3 toSun = normalize(sunPos - isectPos);\\r\\n\\t\\t\\r\\n\\t\\tnormal = -normal;\\r\\n\\t\\t\\r\\n\\t\\t// Visibility test\\r\\n\\t\\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\\r\\n\\t\\t// float vis = 1.0;\\r\\n\\t\\t\\r\\n\\t\\t// if(shadowTest.y > 0.0) { // something is blocking this point\\r\\n\\t\\t// \\tvis = 0.0;\\r\\n\\t\\t// }\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t// Phong-ish shading for now\\r\\n\\t\\tfloat spec = SpecHighlight( -look, toSun, normal);\\r\\n\\t\\t\\r\\n\\t\\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\\r\\n\\t\\tfloat ao = ComputeAO(isectPos, normal);\\r\\n\\t\\t\\r\\n\\t\\t// Apply lambertian shading - for now\\r\\n\\t\\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\\r\\n\\t\\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\\r\\n\\t} else {\\r\\n\\t\\t// Background color\\r\\n\\t\\tgl_FragColor = vec4(0.5, 0.5, 0.5, 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/rayMarch-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 17\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap f67c532b5f68b14de2b1","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/rayMarch-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","aspect","updateProjectionMatrix","gui","GUI","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","buffer","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","composer","shaderPass","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","vertexShader","fragmentShader","renderToScreen","addPass","getElapsedTime"],"mappings":"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AEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa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A;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,QAAO;;AAEP,MAAK;AACL;AACA;;AAEA;;;AAGA,0BAAyB,oCAAoC;AAC7D;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;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CA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,YAAW;;AAEX,+DAA8D,uCAAuC;;AAErG;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;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E5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA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;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;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;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AAC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EpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA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AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,OAAO;;AAE1B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;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AAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;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EA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,8CAA6C,OAAO;;AAEpD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KA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CA;;AAEA;AACA;;AAEA,uBAAsB;AACtB,uBAAsB;;AAEtB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;AACA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AAC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AEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB;AACpB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,8BAA8B;;AAEjD;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;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EA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,oEAAmE;;AAEnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AA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EA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gBAAe,sBAAsB;;AAErC;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gB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EA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;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CA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap f67c532b5f68b14de2b1","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
\\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
\\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
\\n \\n
\\n\\n
\",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nimport {PROXY_BUFFER_SIZE} from './proxy_geometry'\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n var composer = new EffectComposer(renderer);\r\n var shaderPass = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/rayMarch-frag.glsl')\r\n \r\n });\r\n shaderPass.renderToScreen = true;\r\n composer.addPass(shaderPass);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n composer.render();\r\n // console.log(composer);\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\n#define MAX_GEOMETRY_COUNT 100\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 8.0\\r\\n\\r\\n/* This is how I'm packing the data\\r\\nstruct geometry_t {\\r\\n vec3 position;\\r\\n float type;\\r\\n};\\r\\n*/\\r\\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\\r\\n// uniform int u_count;\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\nvec4 resColor;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t *****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\n//diagonal is the vector from the center of the box to the first quadrant corner\\r\\nfloat boxSDF(vec3 point, vec3 diagonal) {\\r\\n\\tvec3 d = abs(point) - diagonal;\\r\\n \\treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\\r\\n}\\r\\n\\r\\nfloat SDF_Mandlebulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i=0; i<4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n resColor = trap;\\r\\n\\r\\n return 0.25*log(m)*sqrt(m)/dz;\\r\\n}\\r\\n\\r\\n//Operators:\\r\\n\\r\\nfloat intersection(float d1, float d2)\\r\\n{\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 )\\r\\n{\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2)\\r\\n{\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n// Returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform(vec3 point, mat4 trans)\\r\\n{\\r\\n\\t// Columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\n// Return the distance of the closest object in the scene\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\treturn SDF_Sphere( pos, 1.0 );\\r\\n}\\r\\n\\r\\nfloat mod(int num1, int num2)\\r\\n{\\r\\n\\tint div = num1/num2;\\r\\n\\treturn float(num1 - div*num2);\\r\\n}\\r\\n\\r\\nint sceneNum()\\r\\n{\\r\\n\\tfloat x = u_time;\\r\\n\\tfloat cycle = 90.0;// * 20.0;\\r\\n\\tfloat t = (mod(x, cycle)/cycle) * 3.0;\\r\\n\\tif(t <= 1.0) { return 2; }\\r\\n\\telse if(t <= 2.0) { return 1; }\\r\\n\\telse { return 3; }\\r\\n}\\r\\n\\r\\nfloat sceneMap2( vec3 pos ){\\r\\n\\r\\n\\tfloat t = u_time/4.0;\\r\\n\\tint sceneNumber = sceneNum();\\r\\n\\r\\n\\tfloat angle = 2.0*t/(2.0*3.1415);\\r\\n\\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\\r\\n\\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\\r\\n\\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\\r\\n\\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\\r\\n\\r\\n\\tmat4 northMat = mat4(1.0); \\r\\n\\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 southMat = mat4(1.0); \\r\\n\\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 westMat = mat4(1.0); \\r\\n\\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\\r\\n\\tmat4 eastMat = mat4(1.0); \\r\\n\\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\\r\\n\\r\\n\\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\\r\\n\\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\\r\\n\\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\\r\\n\\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\\r\\n\\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\\r\\n\\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\\r\\n\\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\\r\\n\\r\\n\\tif(sceneNumber == 1)\\r\\n\\t{\\r\\n\\t\\t//SCENE 01------------------------------------------------------------\\r\\n\\t\\tfloat dist1;\\r\\n\\t\\t//vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat);\\r\\n\\t\\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), cwMat), northMat);\\t\\r\\n\\t\\tfloat bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb1 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist1 = SDF_Mandlebulb(newPos1, power);\\r\\n\\t\\t}\\t\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist1 = bb1;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist2;\\r\\n\\t\\t//vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat);\\r\\n\\t\\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), ccwMat), eastMat);\\t\\r\\n\\t\\tfloat bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb2 < .015)\\r\\n\\t\\t{\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist2 = SDF_Mandlebulb(newPos2, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist2 = bb2;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist3;\\r\\n\\t\\t// vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat);\\r\\n\\t\\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -0.5*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat);\\t\\r\\n\\t\\tfloat bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb3 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist3 = SDF_Mandlebulb(newPos3, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist3 = bb3;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn un(dist1, un(dist2, dist3));\\r\\n\\t}\\r\\n\\telse if(sceneNumber == 2)\\r\\n\\t{\\r\\n\\t\\t//SCENE 02------------------------------------------------------------\\r\\n\\t\\tfloat dist4;\\r\\n\\t\\tmat4 rotateX = mat4(1.0); rotateX[1][1] = 0.0; rotateX[1][2] = 1.0; rotateX[2][1] = -1.0; rotateX[2][2] = 0.0; //rotate 90 degress about x-axis\\r\\n\\t\\tfloat angY = 45.0*3.1415/180.0;\\r\\n\\t\\tmat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis\\r\\n\\t\\tfloat angZ = (2.0*u_time)*3.1415/180.0;\\r\\n\\t\\tmat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis\\r\\n\\t\\tfloat displace = mod(u_time, 90.0)/30.0*3.0; \\r\\n\\t\\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX);\\t\\r\\n\\t\\tfloat bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb4 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist4 = SDF_Mandlebulb(newPos4, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist4 = bb4;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist4;\\r\\n\\t}\\r\\n\\telse \\r\\n\\t{\\r\\n\\t\\t//SCENE 03------------------------------------------------------------\\r\\n\\t\\tfloat dist5;\\r\\n\\t\\tmat4 rotateX2 = mat4(1.0); rotateX2[1][1] = 0.0; rotateX2[1][2] = 1.0; rotateX2[2][1] = -1.0; rotateX2[2][2] = 0.0; //rotate 90 degress about x-axis\\r\\n\\t\\tfloat angY2 = -45.0*3.1415/180.0;\\r\\n\\t\\tmat4 rotateY2 = mat4(1.0); rotateY2[0][0] = cos(angY2); rotateY2[0][2] = -sin(angY2); rotateY2[2][0] = sin(angY2); rotateY2[2][2] = cos(angY2); //rotate 45 degrees about y-axis\\r\\n\\t\\tfloat angZ2 = (2.0*u_time)*3.1415/180.0;\\r\\n\\t\\tmat4 rotateZ2 = mat4(1.0); rotateZ2[0][0] = cos(angZ2); rotateZ2[0][2] = -sin(angZ2); rotateZ2[2][0] = sin(angZ2); rotateZ2[2][2] = cos(angZ2); //spin about y-axis\\r\\n\\t\\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), rotateY2), rotateX2), rotateZ2);\\t\\r\\n\\t\\tfloat bb5 = SDF_Sphere(newPos5, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb5 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist5 = SDF_Mandlebulb(newPos5, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist5 = bb5;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist5;\\r\\n\\t}\\r\\n\\t\\r\\n\\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\\r\\n\\t//return dist3;\\r\\n\\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\nvec3 computeNormal( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Check for intersection with the scene for increasing t-values\\r\\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\tfloat dist;\\r\\n\\tfloat t = 0.01;\\r\\n\\tfor(int i = 0; i < 500; i++) {\\r\\n\\t\\tfloat dist = sceneMap2(origin + t * direction);\\r\\n\\t\\tif(dist < 0.0001) {\\r\\n\\t\\t\\treturn vec2(t, 1.0); // intersection\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn vec2(0.0, -1.0); // no intersection\\r\\n}\\r\\n\\r\\n\\r\\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\\r\\n\\tfloat dot = dot(normalize(toCam + toLight), normal);\\r\\n\\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\\r\\n}\\r\\n\\r\\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\\r\\nfloat ComputeAO( vec3 pos, vec3 normal ) {\\r\\n\\tfloat tStep = 0.0025;\\r\\n\\tfloat t = 0.0;\\r\\n\\tfloat ao = 1.0;\\r\\n\\tfloat diff = 0.0;\\r\\n\\tfloat k = 72.0;\\r\\n\\tfor(int i = 0; i < 5; i++) {\\r\\n\\t\\tvec3 sample = pos + t * normal;\\r\\n\\t\\tfloat dist = sceneMap2( sample );\\r\\n\\t\\tdiff += pow(0.5, float (i)) * (t - dist);\\r\\n\\t\\tt += tStep;\\r\\n\\t}\\r\\n\\tao -= clamp(k * diff, 0.0, 1.0);\\r\\n\\treturn ao;\\r\\n}\\r\\n\\r\\n\\r\\nvec3 backgroundColor()\\r\\n{\\r\\n\\tint sn = sceneNum();\\r\\n\\tfloat darken; \\r\\n\\tif(sn == 1)\\r\\n\\t{\\r\\n\\t\\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\\r\\n\\t\\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\\r\\n\\t}\\r\\n\\telse if(sn == 2)\\r\\n\\t{\\r\\n\\t\\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\\r\\n\\t\\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\\r\\n\\t}\\r\\n\\t\\r\\n\\tdarken = clamp(darken, 0.2, 1.0);\\r\\n\\r\\n\\tvec3 a = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 b = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 c = vec3(2.0, 1.0, 1.0);\\r\\n\\tvec3 d = vec3(0.5, 0.2, 0.25);\\r\\n\\tfloat t = abs(sin(u_time/12.0));\\r\\n\\tvec3 color = a + b*cos(6.28*(c*t + d));\\r\\n\\r\\n\\treturn darken*color;\\r\\n}\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n\\t\\r\\n\\t/** Raycasting **/\\r\\n\\t\\r\\n\\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\\r\\n\\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t\\t\\t\\tgl_FragCoord.y / u_resolution.y) - 1.0;\\r\\n\\r\\n\\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\\r\\n\\t//vec3 cameraPos = vec3(1, -4, 2);\\r\\n\\t//vec3 cameraPos = vec3(1, 0, 1);\\r\\n\\t\\r\\n\\t// Circle the origin (0, 0, 0)\\r\\n\\t// cameraPos.x = sin(u_time) * 10.0;\\r\\n\\t// cameraPos.z = cos(u_time) * 10.0;\\r\\n\\t\\r\\n\\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\\r\\n\\t\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos);\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\\r\\n\\t\\r\\n\\t// Perform the raymarch\\r\\n\\tvec3 direction = normalize(point_World - cameraPos);\\r\\n\\tvec2 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\t/** Shading and lighting **/\\r\\n\\t\\r\\n\\tif(isect.y > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormal( isectPos );\\r\\n\\t\\t\\r\\n\\t\\t// Lighting\\r\\n\\t\\tvec3 baseMaterial = vec3(0.1, 0.2, 0.2);\\r\\n\\t\\tvec3 trapColor;\\r\\n\\t\\tint sn = sceneNum();\\r\\n\\t\\tif(sn == 1)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(\\r\\n\\t\\t\\t\\tresColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.8), \\r\\n\\t\\t\\t\\tresColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), \\r\\n\\t\\t\\t\\tresColor.z+(cos((u_time)/2.0-isectPos.x)*0.2));\\r\\n\\t\\t}\\r\\n\\t\\telse if(sn == 2)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(resColor) + vec3(0.4);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(0.0, resColor.y+0.4, resColor.z+0.4);\\r\\n\\t\\t}\\r\\n\\t\\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\\r\\n\\t\\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\\r\\n\\t\\t\\r\\n\\t\\tvec3 toSun = normalize(sunPos - isectPos);\\r\\n\\t\\t\\r\\n\\t\\tnormal = -normal;\\r\\n\\t\\t\\r\\n\\t\\t// Visibility test\\r\\n\\t\\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\\r\\n\\t\\t// float vis = 1.0;\\r\\n\\t\\t\\r\\n\\t\\t// if(shadowTest.y > 0.0) { // something is blocking this point\\r\\n\\t\\t// \\tvis = 0.0;\\r\\n\\t\\t// }\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t// Phong-ish shading for now\\r\\n\\t\\tfloat spec = SpecHighlight( -look, toSun, normal);\\r\\n\\t\\t\\r\\n\\t\\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\\r\\n\\t\\tfloat ao = ComputeAO(isectPos, normal);\\r\\n\\t\\t\\r\\n\\t\\t// Apply lambertian shading - for now\\r\\n\\t\\t\\r\\n\\t\\t//gl_FragColor = ao*vec4(baseMaterial, 1.0);\\r\\n\\t\\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\\r\\n\\t\\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\\r\\n\\t} else {\\r\\n\\t\\t// Background color\\r\\n\\t\\tgl_FragColor = vec4(backgroundColor(), 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/rayMarch-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 17\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file From 3ae67eb7f0558dd1953f5b6e0e6685e85892e7b5 Mon Sep 17 00:00:00 2001 From: tabathah Date: Tue, 2 May 2017 22:50:57 -0400 Subject: [PATCH 14/20] audio added --- Dubstep_Sub-Mix_2016.mp3 | Bin 0 -> 3292905 bytes new formatted matrices.txt | 18 ++++++++++++++++++ src/glsl/rayMarch-frag.glsl | 15 ++++++++------- src/main.js | 23 +++++++++++++++++++++-- 4 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 Dubstep_Sub-Mix_2016.mp3 create mode 100644 new formatted matrices.txt diff --git a/Dubstep_Sub-Mix_2016.mp3 b/Dubstep_Sub-Mix_2016.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..619001403f19f0c049f73910038fa34880d0aa0a GIT binary patch literal 3292905 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%0A?8gkPH!l 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

P?ZDq~uI5_INK#pkqerp&YeqF4%?KsXBS@YDD` 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�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

-c$@B%CIF_;Hb> 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
ye{f@EIsKWh#idNqvP>$09ODdcz1*>%&Mg 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≧̸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
Jl%KAx?&P zb64vZYll6ary7=Yntbm}NxcZ&LNgEp^i2l;9&2=sZELY3M7i!zglB{a2a6LOJC! z5-Oaw*P&DCusv-aG5Kq&bHZy&b4MyaIXp)3AZ(`Qr>Vi%n(ecGt=L5) zHnDWtz>P(@6v0I|cs4*As)7WUl*A$6LhuVt5pgQ5|Ht#Y15_<*tH0^huNn_LuDSTO zkvI+b9Y_LR>;eBey+Kbd;LpN%vIY!^s~ANF`Qm^@!HgK2 zOkR0I&ZRMzg6ga&HioS<3`{_S@B=k3rjs$lLI>gUq8gR`j~~}_OJ|S54-bZ@nw1-& z@FqXw&%ZI{)_PK0>vejQ-_kpRWB1zXAbZZ$26{TXC!z9p zKd{?!U<9fNu;JPY-qto^`#qJ!m8H4a1-P{T&(9XxCCJV-Av)X2cOV`>Bpwq|c^CvE zg-;BS|HuLXc4>Hcp+=apy#O($eJX6LO0^`yYdrDHFc)gq zECczmPE&B7j4#d`L5z%d>Gq-WnhAlM78NL!e1ChVy}EhS{`((!+&IqBZGBkY8*~$`S5Kd7f_3t9e(CXF%mE*Q(#cPcI^`lvd489wQ z97EB#Pgt-i*Qr+YDH6LEow!5U4Z0v z*tNqi3?t$K?nz=jbXC%tJJtnTax}w{--!V~@qdf*<{2b?pqR7cqus3hP;dHvi~mi> zEoKki{eG94c7%VJ9#a*dWcB-X%ZexN2Lm{27O8pbM-2 z`A8>A3kxLu3fcA-G<%O9ZXy!9~M)`J&oBJi-YAh!r7vCX8Vkuq{hOH+uun*!0Y2v{RU zXVz`Lzaszlb=REkgc>DqDeTLU5XltR=)h){>$0D6x$t3$Bi-CG{d&n-QDq6w@b#r zv0Tuy*)f;BaY~6rw1UGFuJl{(^?}MZ`pT>jEJ1_)$fF?+YE-+!WoI7f_*u%uh?edc zk?QcT&eHvT=BerYBOe6ElP)$fn2Oqq!9Bd^pIL+3cR154VC6b$P19>78zbqr6} z7njr{bB8okIf9tIjan&os_JZ&+xzAp?8WNH-Hv=Ysyb+n z%&9HC9wpWa(&@4&A}jUVdJpN`>&a9m@J$;Zg<-A4Tyk5nX9Rw}bi&TK&zx#uSG&RI z{n7Chwl+W6u{T~jWkjeD9YS1z8)+g291?-YsZ`H+MH_Tz0HX+4of3f-Llg^3DMtVU zv4jSljk~{f9W2C_7lDGINyDuCu^`%dZ!L!l%b3Y`MYvB=Y~l)uv`Qe(U^22@%?dtt z)t>qHwnmkKUV=t&Jf6K_ z`54hkg*1g-8i{LrSd_Xeo&^!$JoiCV(M@iVKKvlPkzIXiJP~(BmRg;%$VQ!7ttF~f zu8%t>)}QKR!iKfl;)qwRO{%7Y=G<&DUno8!ZFubuHs(0e99wF;GeD`UK{RL({xS>= z*uL%&n^FE(J$sL|$mE|WyeIx~^!OMw`n%%KT>#xNolG9)75>c>wt3IRdqq22_KDwA z`}|D(cX@4yLk}e8ZZUm3OQH8)fP4ktS~LjfmgnbHcuHO3rsI_|z;m!!$g!|uj4!=f zxn#_2s8%K}_aesOjtEL~grbH-Lpj1z`{)XU5`Q>~rl8vCHIgM`9g;C&4eT?>A|rB0 z(*<1x?Jq8Ru$iBRorlpw$ZST>Ji?flFQhytTT+-&=;l!wE9;eNlL17j$|zAW9n=Sr zd<;aS>uWUR7x+?Br%lrP@BwYD9s`!i1p?lD%<43=}Hthu{8;^cqj*hHEmF2!iHpYRPlTaYYy3?1l8`L z=-ML*Tn(m)h-v)#%@$TXAm#8J|DB3wuKgtM~(bi~+ zI!kY&^)6k=zS(jWoyPTDO4d6+@hb{fyVdhAG)l0x%c`rIG;A@P=+e_2>;u-X>UW5m z2rBw`xCA~sYM)+hyyg9kbGSYQRf73 zNV?B31Oy$iPid0PUY1Ud%&DfZJIu+N@%6ctM?6G(6ee2mB25dOH#O;()AZAnj|1vm zxW1Y1l;~?%upjcD)+M|ir{HDA@@BQc;w&i`tT=^RGiDp~rtb3x>#Pyc9FYoao7&at zZH_q>RHD{M50`IXR)ofgM(ZuVNY*T%#45Z9(SfbEXuxFfY6USckm%+BwCiB zSrjaBHPI?^R*-7~e|j!PWRY3b2#yw+@|ORbgFQi5_CS3;d)Iwb1rXGD7R$^>4DFsf&Ak|5+woqN2((n*dsQyL- zNSKXK^^glEB|9IZ-1lr^%Ezu#L1f=nxT36H{-y{&N3+J{%&eN&I)$QjmpD*BSpT*7 zn4DVoPqM}E0w+JB$#9RRU{h~c@BcWOwu3R!(r%(14R;>=NjjQ9(V8$fZj z0i?oEfF}kFDiSDVF^))`HZ*H3hoN18bp2c z6jxiO0ndwB0Xt_je*5khQb?~@U!TSOgKErg8O(t|+@@C}&0usXX@wL}A{gaA*1FA9 zRPF)%W?9n#=gB^^w&~GZTd#tFB10#IIJ>wygN93|edTx`b(_*~+U>Nk6Au{xI<{!*EFCN(%^OMJ0@NcUBmz3C;ukKajj&4Wy`5_ zv3sq`_i`7|OPrwl<;`x?4-Qdf0ZF|e3k4F~uTU8AW?~f#?Q*&#z!(E3H3o%|KuL{e zrVs5Xp`d)@TBMNxj5IJrAVOi)<^{zDSSq-(OIJ_9;$WZ+UF&dDuGovj4Qq5{(u5*=TN~=1-0mQ& zuUC5-`dnj`d)m%8F|Ec{?V8Blm@{fG&~E4N6i-Y%u7M+pf)Q#tcq+F@?Ak?l2>vKK zyA3@yG6`R4Iv1K}m!de$S1CIEUE3RNx7RcL`&Da9j63?bfh5X@Yb8^RuoK-ZvX>{B z@p%D(Z_6P=v7(hukq^#E;%vmrmaIYy4;)n9Zv!410|4MK)$hqGDar7)*P+ie6wIVn5_sI0-?(II4$l99x(DNNm8C zpF|=GuXpXwHy#0B?^tvD{$QTXr<=opelhnbZL{C7b*@;#8tmbeYSVGyBq0lq>&J$ zTLh%*;q(1H2mjN3cE@Yo*S_~!?}aE-_$m}>0YINHR`&;o;i8Lgn7sb85@N1m z3e$3!SER>e7#d??umKrRl>?elhDOngT~oo>VER-+dTF=#nevA*~h<&e8nW76j434lXxbf>50QI-2` zL|bNsN}_h@!u63|v1k=-ZcB72K6oM3(W%mYxH>b7X8yjUwjSw@2)mB;rl~Mrx^smw z{w-g|Z9k-b@rXk|E%D^hg`t|?gMhnlq5Qu=;RyHox78Gi&qw%eg(BdkU6z{Rn;7;B zp%I(sP0x!aD6NR8PSHqiNir^k1xB?W;Lm=*lyO$1OShjVY;btH)5;uejuYR9E$^WMStlZJLNpCO)ui?UgghoSP{xRtl%9m;h_fxgY%`%=oF0&r zM8GWhg!z{Dc$S`kIhw594f8gtO%76g2mbew?#pVuL{~gvD|6zc!{oZG^(RVqa>1yE z23u}A)53MBsN0@{sYaiC<0Ixdf2N|iSr2CqvesC?KQ{#sxIk-hqicI-kq5B#?~}`0 z*KeP8vCULIb+7T2jk&x=G1}VV)I?9j}QHGx4q)HT6dWC;xTB3OhSD3n+c@hD7bA#8ZrW_Yit zsfQP-L&H!pRm7v`NYH2#Mq28L|BPovo0t!4VUuQJyka)4=ta?!V+d}GKg#{77AZ6r zB(-n*6<5kKih3N#^%-W$OoC}4N%~K7hGny=*wy9x48`V&E5)u+uEO^HLffTMCPL8d z>mkv?Yu44DglEu&_uPeA)AzDvUyXO}wO3CKP1vwZ2>JPyw>WKlFLzu`Ba)V9B|kP( z8mb*Ud3~4d=QP@bUm1~q>M5ZQ*hlK&-kIpAQJ#sT=_7vhKg40lhzYVX4~!%$5=e)H z2%9A;WFq%S2qi`2fupaKk&#f8Bk*Xn8ejD|#+CWg<}5IR4_CSKEYSK)X(ic0o{=+f z?64(rgNn7y=EPNqC5k$&5DxMmd<>@M%DGd;(?rD{r7&hHu|DB6{HXW*7L=RzL3lNJ zZ<7J!Voz_meLZ%?l@`K3SzxKns;i@uUHteZmswiOAv=1ArO=!|FPEN??@O;~z=Y=4 zn$wjHR@}uh74w#0(S=T$p3Y?xYkoiM7TJFOsJ>1C-xZAq=c&)lm|y2^o3;ZxBqBdq zh|PQjC%&Q81A-bi<4DAtpV*%ky=NGuDCLCcEs}jOdq`_;2qE`KAnFV<9W(+JYNnSh z7rkX43e*y9GMtfz8bCV^wgAvnrULSN>wn!jY%B8&+*4X~{OIo67#MrgEzouR{|lcMo6I&D_M z+9&eKpQewKRQa{xXY!Rnj~Ojo;+mpf8>M91Zt-}ZRz#A0T~({3OXo72?h%Ii#Zj#t zHu1Pn?a#zlhpoP|*)o<^xFBfE1G}*H=ZVs%s(Um#;St>vDNtlin0eQ z@&aNCVtaZvr6qCz3g|}o&_v9+*?!4TIZmY!6ngv>Pb0aW9BAX>JK44~&zV$JwC*-p zBh0^#0&$z$=RytDwMm2SG|^!i@OWv?ukw(;`e`Zx>gyCymmng)@fs>h1#9doSS9p8 z>gDHI#dlY?fIShh!uk}iD@XSYR+^=XwpU46QTUvj z&OR*)53+Wc)Uw%G_ZEV&pld$zKBfj_+;#avnb?f}Tr`%uL&1JfZ0fgI@i7__(1V)q zW@?y+T0t+D=tdFG@x7GX5+z=lW;fJ^w4Y``6&*4tI;u=T<0YXPF$tKls1v1T*0nVw z&?0ur&C3T-m`)cauC>|NPeT5V*w@jWY9f8kyh{^;&vduPPgqgELyJdg*UQAdlw7(q zGB42XDOzaNWyXhiuMS1bzawF1nO)tE3u4tKG1UI<^f?P|t|bgl5-G~>Fj&{C$?eJW zIgQ2MuA!^$8kkMUQ;*{{9_-+5#`Sb8IUMW-4hez=Z=iw$7VqsVkcRG z%L_!8sk%d8_)Of|3u*={(8Ye^}paW8oNTb`->>lM*pw$ zVf7_A{Q_e%*u)(tv%n#pa5(Kcy4)`M^gML?W3`zZpPy)4v`jZ=`~LNqT5mXD&_p21 zw%1%+VadeiGkFFZu^Bj{7TS}OjEe^7(*z(FqcSK%rB(+@(1LNvpz@%IH;JT*0o?`T z!)hh!`C-&#JCbe~5ZJ$2Mp3Ps2rONBJh1dG3IR+49%X5ual;}j+z}jAUBoYs1_CQ* z|845do{V{mD>IekL(ZC)N~ZYgA^e=|yDlxiM)IX^%jheRGqlir<}eE6<(p;c@1B{w>+nee#`4Ml7nND%MaNPOCU{(vVkB80 z&;aowOaK#D5I};9&4@+JgQASM;0Ph4wpE&1RAG^rE*Mq52?Oz-5oy@7FxBe6c-NN$ zaxz^NoJGOiY4YHbg1>l?63E-M!bbw*6J}8XRN+L|;=$ctCWL`*2KQ6fU7KsYLdrxm z>{x2`bU$VxwUlE?z8}&ED2A-wPF)Ew6i+3wESBk^5C0&lHLQCaP$FJ-N!E4JVCO$c zLT=SYTA_!i-3oxga#|UbZ1q7Xj#pr%_oZXMutA~TYiV>v3lu67M&dq&o|GT zYUqOzQ37mK_(jm;(=IDME{HtzCoMMx1J@^R=uJ5H8wKtUhFnJUP$ohsy)-(d1U0j( z65K3;C1eW#6jsBJNHnW~p+lj)1Kp#eI^tx=q}+IB2?^+~0Vqir8M$f+QODf1IU8W{ z?!50oI4FX4T438n8Gsy$d;luIP9FJ{I2*FjlB81A;MG{_9IK=Fo;uOd-^5SiP9l$TdFYo}BcajbSLiBc zNXcy0ZusTM0lznF?6YmPOIs5=f6vO#g}^gjC-Y9ica<)^nFb?Kx?WvF4SGTi{+HDq zrymwBW8`{LnxS{2AMx*E__0Bf_}Jul*btW(d{t1xqOzu_N(>)*5DyZv1qvz;I7kPa z$%qqO^t*d5cyxcHfIIP(6?3^VC7~$#B$f7H2HvoAI2}GU0wdkr3PGx!7Xl(prjmz% zSAcpl4Y?cr(lJcQFd#Z#H&JUvy>>z^dcZJ=B$A5?Cs9D)MhQ}!j8b`R-S#>g`I5nQaQsiX-+IQHoPGPw|j`v`w5kNgkYN)?&R`%*cL z3gjyKuX0+<{#k4}X~C&IWAIW$S)O0pQj8EEAW2&=LirPdobkv^Z42&6Kr7PXf;jnF zJ5H~Z%N4UAjAkWF9W&F z-zuijUd;7q6n*&McWEJ4oP<+iXOUgpvFmg=K66ZSmC8b(96`a?V3^>9=x(9M4m-nu z?~y#U4N%2Fr-Xs?iy;9?wPCAs<&p~8ZTpFhl8tC<=Z1UZfqS`1DkJ}`q1KX3`cush zvW5oyN{jVVp;bPWFrP`2Acb{Waf1AHy9WYprF6z3*f4vU?4D742l$q6{M2!mr>j&h*li-fq>+&`+&kLFGgVqKM{zrB-`xZ~f zi7?^p~D;uk`1q#dlr) z8B4uGd=?lT4z12ZpIx-M_m2D@hORF;ml6(jHBiIG1-?ROKqG2WYK!Au_PmgYJ{XD^ z03?Xb0}DW>M?#K3-9-Xs$OB;jd_Z^6o2mQU=?G*@;=lnTWopSlh$M+tuWJsvGFFHo zgElD|DiG2;l*?>})BE$U*c_8a##lreZEqevEf%0E`sZO4+?|n{#o+4Q0v)bi%v63( zLeeih3u`P{&0+{Bf$1lgoqgv=mT8%PK{5@!3&QbrO!Rct_@-bmU3dLocV1N&XA9pV z@6N-L^Cl8R5Z$I5yLbRTX=vl((*?FEwu{!%+MjoPX%tSY7^Bm|W4C}L@+k_p*n|$H zCrV2wUDWxHBazmXg~RLTXOoKsN4O?qME6;&3mZeyM=lnx+%I*-fBHO4CmZhXAvX^H zm#4Y^|6?_rsn;U)&!MUoE?C-^S1+NS$&HG8&aXpm6+7B>C(FiON7@|@G;cKIIXrk$ zyF>Be%}6{Z8h_0TM;k3nW*j_P$;MlxSHbMnZguGP1MiyTFQWinAV+ zbo>U(sZtoMKN#>82(Cbp*`kp4r^Uu1f|;0?AixTc%(`Q>G|} zQN?9|1V#40r_{7>q~#6;XK4Nth5Z1`xEM8{J2i@KViaJ~5@5^_E=$=CK#8rhd(|8O zs3oI|4^~EvqNH214?zz2@si0BFt3S1h6dz7JL*K#E$;gf)10;^*G25He5Ru1M+OyU4ojf`{Ev#sT8w&)c35?ZN ziBCD;YyYJ~_DUs(t9{ha_3Ug7{d{%${M2?T;!o=FlY#uq#MJp4WaZ4mdofOqq2}Me z$j6We!+N*%)BiWk^f-LUp|v35?EL8PYXM^Owant%##jGq4zE-@Ca-qBv`@Ri8Py7TpCTXG7JW1MfA&k)xkWzNtY~U_B4J? z7@jdb;o4eW;?iP!!k~#cajd(&t|R7T))!EzY18qUtmEbhcSxJ8O%!(!Ag~_8D2h}~ z#}%Y+H5dIUlcQnRD+@WbqXzrX%d^eLr0t8K9bTz}f1*cM$sFPD!DsSRv{5!BIIE)MtMq59w}RZ zP+I$qct#wOCmG$J@48Igr4-kg3`$5GjqG;rI0TYmYrHNW8L&Heel~ou67n-3VADIY z+x(ELhK$e(%>QmxE~}S0UEpb3oiq`)L%h(SUfG8G2cGt)jpXAa`Pa10siJ_cd_09= zO|i5-W~{>efc(1Q23ZGo-INI%6=xm=lEJX!vN?k*{llh1n`>vyVfY`P z3Eii)A)E_u8zlvs^Irz3%`ac3X0E};)wa>^Wq=c;nO^gj~xoVnk%v*Ha?94c}@Zk&P1IQ8G zhWpD2U+kGfTHl48nMf*c%zf?>if1g2PNBz`=5jTU)l;9X)@~?FOO2dytDG;ms^6R5 zoWXKLSI=qb`G|c&^PU9!O@pr)m^MyXGcX2Phy~unl4S*#n-ib--fdA4hj!QqG(PcE zKR=UKv~FzHK`Y=dr=WZh&Rjb(P{hjzJrY{t$OB-7qUt~c-azREpcEK#yW3`9>1Z814{fu{{n z!eTOjD!8Y|pvcu@) z35Uz zeXcD{F9{EZ%ByozeSmVKgr(Zi(Q(jmQ(moTT}6&AH~xt}#nn5^8^^!+^-T&HIqDjW#ka%yN=MpNh%n2GF zuRm9_dwXssOOkIkPT*#` z=eW&n6^x0Wf-D0<8XyI?)q%m$BZ@#Yfgk*O@JL;isd>d{KVXs_a9@`6#Q11uJicYC z1O+ayTC!L~ec?;D=*(mnHp8`9SA&xx6g=psGg!!TQ-o6zBQy1^^_{hwAb1FU+1cn2 zVzzgB&S7t(_IUv^L}SDQ`Q82Bpy>Ebo^uqJzn*W3KbGmVhU02LH@&X&mv#JRYKs={ zE8Q>8qI4IU!pk0xW|SVcsK_RDxeCfmGKyYw*@ZyfU!PMON+7362o{AVy{1F&9)gl# zTwrM&L!nst1YlFB91;&ojUx0lARiS<3k4!c0I(tC$TP~_0DegTkovn@kR}#$9@R3xAV~APOz7&Kyz%?*~GlL9GJqR5cEdbO_0RW+QYct?a?G4M< zBhgoZ2yI=DwMRmH`~zt-QVM3HY67(Iw7L~gtxK6fWo4Yi4uNVq+n zh;4~;^IrI+^V;F4uP~qQRP6o9iILwP&#vL7pT&p8yMOC1JU9J`PLGccixVmf`!Z)Q zQ_tfipIytz5$0>HJIen=;WzHphWR+k@<;e@5CZ;@)0rl*oF3=oq+g|x{y)TuW$J6< zVDhO$NCS+Dhb61qD_b@KqQxG7dVv*>TvGKy)`0=&tq<*$*&wp68tj$d_e87+uF|ux(-2aPm*U#j) zCe?l2^0nC^%lwhwC2e`445ESfqd_|lvf?{C zPX*7Q7xv80UknkA@s)2COqoAaJw6m|X|#7%d2gtcTFw*QqNwz-dv!hh@n6+H4yHJ= zT7RJ{Y&jb9=QRvIHu<~kb9GzsAiJh>xl#}Se}_Obi1TssrlCIw!M4Q2Na)?Xc*=kP zweA?C0C8m+R034^YFT=2H{(&xrXK=i4FiZ1_M(6k!Sb%8u8cd6s;%_^R4@RnRtD{h zlwq8~Rq2LXp~a~3djNx1HXy_~p={M6e^a8;nh?^I4r-F~_E6p~%~>b)_Q73V{P7$I zcc)&QdO*sno`0oP8h?_r7u;%ENRrf^n5(>3i^lZ#RG{-+-+vf&WiK+H4L%v1a<%FF z>w2cRbRl1l(|yOHa&7ofGX~Y)5yQF^$579=7a(I*}}t{OT%cq0}A4m9d9qI|jP2MTIbYBE>^iX^o<6a(N6 zNO%jiK%;Jf0W*ZffDAW3qVk);{U%14_TWVG;G7(IEdgvv68xlV0JKCo>tK-@q@C;9 zA0i}`1MF%7*VpkEFRw_=?7=riN5}?ny)M61QHtV~g=bQ|R1gn&A^{;i9eZ!eKJPdN zI&hp2D^Pk`OX)R43CSCRkBkB2#FIrvZOnl~hI%dHVwA@iuMXjJSqc`R}?K;F)$6@Mw2JX%={L!;+6jsJL<0@uFd^q%G$ zuylad&5zNY+oq$yzk$Sfp7_DznCKkk?>JinQ1B7OGTY_8UxHXe_n4gm0NrqyEiw*Z z=qnFuaEOFE6^Vf;Y5a!4?oBb?h}6~SPaj`;?kht5mEUS2K%cPSU~vdatJRO^$BX#Y zyg~S?DO+n?f~_|iiWG=%QXCbF)OGIp{PYx|;Pc%6cbA~L{h`aJk5sP}5-uV?tC?!m zSX7GBcx}R!b&dIbjP~8#|GUk(C))A6t+IK+yd8b{-}<%F@n=gd?o#%#hwQ%-$J2)UxMB|(A8(|pYdey2@N`BIPnAxeGDcIwjgDUJGC+Z&_mslV=GPx zQKN)_r69ir&zA9HF(50dv5FyGQ&JD+0d&$pVGT4Z9u!S;e$J!0amrZ&Tnd!HWaZHe zQ1^b1Y;S;b{Wt8TK#;ePZ(jDy7!58x9Xbma9BD)MWVuxNZn9-p7zOPe+OZEv#RnoW z$Ot5cV8Q}OC%asgn)mWlKZrInQAFeozs5vED$Aw^(PIFD>}-9?$^U49B=td6*9Zw3 z@EumA*>6CN0-iw=2KW`A>V3HjrPt-kgWKNTy|wAeW9)2TNJv1INDhqp7~#<+4^lj8 z-~Du-J^1{*@+0|g)YZYo&EADuo7?KPyn%tVw6kWD5%*4|CvDofKu$Z=t^fafi@jKz zEkHcaYyK6`|66_^LHR+Jj=NMjue~#h#^10SRg?>fYn*J zQQih~(xjT~pQHYcYP;MKM7e3SF+3}k_201+&Yatv&NeP(!id?bV>=H~ZWQ^gQt=jv zm~Poa^%q6?hXJ%XGM6w6O=9@bPy0mIPnWB$ep#P0=RFs6yUqBF?#AHBedEbM?`5UU zuxLXam3Clv-KO^PJNlpA7+33KMxS<>%{b2@bnn#YMeQdyt|h{AT8xkW6NONmeQz&~ zbO&lA64gVE}+~+CGe$q9SfE9YXq;zw)}$e2|Mf*nr7@^MHHLjY-@=d zHu`-D+qrqedtUhAup$IWak^<6XP_ky=L7>KyTYO`MR<0x3H5;@(=8<68*9q?`}dc0 zB#icZ_D1~&`vNQpMi_{K|*?J!m zCgD;$x?nbGlxp1id29bc3EIltYIbFY)3|uK7dxXw88J4&95-BQQJ-XO%3KiiO-=(j zab~z$_LreQ@9Eg?tw3tjT-VsGi`aF>R@G;p&zHB$S(sB^SVo7WiR|p34xU4QTp@?` z42&aPTxfZE&l5DH5HXYWZW@%v5d#@>N)p1DDFm|ed)&rR0AfyS7Fvl42q${u1)EJ_ zDHYG^{nwt7a8qGh+g5mCoW=3zulTTqMK8MVogj`&Ix?d8&k^9F1D; z#oXA{K#LPEl`p%kvJsPZK}mIGJ&`yL&*WK@Ob07qW0BBk%2ZC|fqGdE7^1HcGr5@n zyUAOmHl|wNjr+S~@8l4-C-v6oL9RVAlyDVl zYlfGz2}L?>CznSgOL2*gS7d`NVcn7>;#&d&Pw>$L)%4OJy5kkx#Jxy~155>7jf&Wt zPxD_n-G0$mz+BoY)$>e}cU~u(PjBO5ACU^3EqRDu{mz^v{72xC>sqq0pYupqA^Mi3 zP{Lq@i(7K^HHTk8oByyGI>G5{qcq#EGbt7l_Vm{he z!;61AM7>N@M3q1Ib^OC03oj>XZ=H`96_c>azmJ%hn&!1OQ9eKHEaM2oHoq=9k#wuY zJT{IiUwHJrzn3dFn0H#S%6D-^K`yG3o8c&%8*r8OV38)k5Mrekprs>?WhLcJx}ZnZ zRO`chL8O6EIwS09U$DFN@Rm(nVj3J7HY?9PGNUqe-!Mx4;(*+yuS{4}9VYI=`XBv2 z4=88OvUfQBYU*@udX>~*%_CA?%rX6wHMXFZ*(7<6@3mG)=lsgA!-flMk7ZGsuXW0D zqiPB9$20u;t9i$Ua*NTpbNq@vVN@ntl~OvYg?yt?Kg{!SUQ>$ZU2;5Po%ozBpU=4t zRC2kK97pC&&)Kl%M=JM^wcQ-)Sl9fj&ewE4SP^+&&7ZeD7+^<{>t4k4{5;bxUMW6> z_pi5)ClU11j2=uN09TIToiPuCf+}%CXiBccM{WX1K4+$_mS*!fxSucS(|q&9{m;-C ziF>u~JcHt60biboQgZ+~Q>b^mFjh{+LWP-n+G|^o8(OVYw1cjG9E(+Efqp|$DaRnq zm}i6G*56nOQsWbcEE?V{P~QB_Su)(0dRHEq)HEFf1cP@&cjhw@S|@!II$@FrKC)HK zeRs3}gk{Y?j_Nx-sAJbgn=wev1~+^)crLRDvJ*YfcnO9NJK)O{&aQk9SZ~EEkFAcP zREZ*DG3q>lhU4!#cVa2(Y8Dph7FBkmqLArZaL_`#l~+IqW?$Nu0Iq=q2vUiXOj2r$ zo|GVLY$i%fm*c}vCB;GY?a(Y=!mmECl00sV4;K{EX9#Vz zxKV%F4S2MI+b*As+gq7DG`Iz(5ykX6rn>5>s;xL*UhRY<)o$sw#qGI7qi!T2Vk%;J z9CgbPd+viQKQPHTh&QAveCP)IQeyw^CQ-h%UiE9fu4$@_#xY*kep;yXihrqcb4}~4 zuu$!|t)i;|TUNC1p^W=j(mc!sDnrpY$&=w+3}}NDjL3u!ya~RF`k3)Klu)zVVf(08 zG)TItQuySNlZT}bCAOWWRM}r`S~Ulqj8o>lZ5bL;4=w9=9gM0O{^DR-IR8>x&FS*cLGqQ{s?Xtb8*3;8v#HA)`X<4uK z9tIAdg&9j)eeDp+Ydtu-Js%|FXh8Tf=6IxB*}3Y!lR^sonStKa+E3o?<{L}%q<)d~ z-=NSJf7NNL7W`spT){Q~zi0yGe5ojo*-P@F`OSacr7Z$Qsx&PdPVay9j$OiAO z&4b2;N72n)#yO0b6%q0vGGYyNmixWR3dB`4}N9v2iIK^lZhoM9$K9D%C8+l>GMEfp7fl zwOHg@k>|>;nFLdyQ(oInv_`Qnb*qsaoNQOOnS+{(>CketPB?RsS}lL*!1_`B9S&~& zFN3q6R$A`cPZpup#dLp=eMHbMH`rB-dSHSD&ie7zSCIOXGP+|Kr^(%TD$E;<$k#1v z^<9xbrJj$(${*Was!E9INqmAy))MIsnneBe>2z$hCiJa~dk?>_e+dcg$?v`m%e&@H zq#SERF0p3jwN&5Jl(g~<$8%N*(%)$!B2|<6&;%xF=0OK@Bx4HUg{3gipo5^Au)i!} zJs9J3`feg@U$TdW(|j~@1*bOW5T6i*a*Xd6@pXU6l9-!~=G=Z5YnB3*$NXvq-J3PH zt;aI+`d<9;kG7@!y?Qqc5aAa}2x{J0%5fL&vUL<+0RoM_O_wU~h z62DH%pVYZY#2*wf{tzs*_chnZ0>S{=UX#J5=lQNN*^!n z1MiI_2Iw%J!rIYUMt-)MIU94Ani+`7cu?s22FwU*50wy-H6leOqT$Omj9cCZbqUqI z_1r9oj7uv+9EUd;E%+L|CMz^zAM(OS?npA4Aof}QdpVd@pyQ*xcz#{6@(CHc+$KFX zYm8M2yFBKQT=uiarlZ(BVxB@^ ze;6$?1Ql!{2%)wI)3Smprp!kHrjncevfohe7$ z1DRtPVTV-#Q}s&xP=mZRkBPZfs=aEGDjkq4L5A8^cx37g!5UABaqeGn%Uy{#a`ogK z37V~AI&?D>Lf`tsiMBL*qAD$4?`d0fm#W1z2={rfP>D?_@RBdTKBaCJ8g%-8BJ0gJ zxZ)=lJFHxyfoOdowv-adbj@GWaA)=1UU{j(&~%OA}0BA3u%*c0X|o<9|hxKDxrUS8Md)D5uMp$+vIn zM{&JpN{f{4Ld2zT3ssM@?roIgxQoikt8wh;eu`Qu^dG@<*zw$^IUsV-8VW-tNN zG0RMQ4Z-8#IlXJ_uY|=QIp|F6P&*jJikJ1bqym%)mHKr~w@hdu z13-tJSh+_ERKSaWudVeXG6F#hM^6f(&4^jz4LT{MNf6H&;UY1@b&&X|o|@I-rbqLg z)$o(#qxdF`gSsBW46v9z`n$^m|KNL^uzdKl^1CniqO%f4J_2=E(7G}rJOZvgBi^BS z>+v7O2f*|LcaRozdQ|A8Fnt9LTT>gwN+*5%M!?2YZi^+&zSb`E^VummPn%*sozyor z){^0{pC6-*2P+#b@%dV=Y9z}ms1T-#L{P6vQNt6uku8A1F{6GCSdg9&&to&b zlrz=?dWm|MWcE~5;QgX#0U2Lq&n+@(!qeQ@)RcpYNzTL{@! zb%KcaT1bn3U}73XnGsT=;Lhbcyl_edyWSK@DW}cpxp8WTN~CK@xj9!f zAGbNZ&n=dwgNIy3;1LW2Y9hzs{>z-$IGHYr4U(TCN!Zpt7_FI)fp0j=E8Y9F=nLm* zdrp+Z#1OdzB3!poPeA1ktO#1LaViPmVg}P<0uvg{;5z>(8r8ofSFje<9AqyyTlU)E|7@eh z1dVO9fY?xlqQ9=GbSr8T##SfptHa8f%*&LM?Cr>d3f2uRG~c!vMA{9?KPivVtPa|j z&TUVpR?#8CS?QL0K6*&M^Df@{$1g;-X4+)+#EP9owu;TI_+%`pXXwvUh<%YJIFZ0s zQDxejeD&X?uor)Q1Xpv$9YGtUmr3EEy5bj~qR!tuQ!W9V z#);a44yU?L4!0jqJS?K2uPE3XJ2Wn^kzz|K_y93OP245COOabVgg?>g31K;;iE~VK zU>RU2bsqz&P=Z>ib#lviA{VoA#2M^BClM1NM4+-Psq`;y*AK&ctd0o-b);zm68%~> zR5v`u#}g88m}o~x7oNuJB=ri3{$3>|7+E4U(^u<_w573P{rI+?y`i&?U=ThBhWbJb zmD4zULU37kNL#$f^w%V=@2920nn>474+(NX{w+PP+1Io(6UdU&^d57HG9*b9o(rD_6qYNJ6(fv+41ucBpphPQn*p#saEWW9%0do6x%pF-TamDe zJ!acDi1{EEHopm<>JRerL+vOu6?o9>aV7@7PI}_6xb#~otP*x#1apwJ=#RFAHlmry zFj7gw9IhT`nZ{4q$$GBowEOMMgf=i3N*f_vcE3=MW4@RvEAeXlH3Kb|&8vJ?DYsfb z+X!h5N2TSID7}zZxUjm`cS*Dxu@5q+P9pj`eC4aW1F3ZS9yV4*nkz0gE*hL&op)}j z-&YSY%$zb=dEdl39xL-Txy;m-o@JWXHoxx}sCs%fS?j38@_&B1uD*BdIQD$2 zt*op!t`_49BSv;B3yw>Js82C~mSoH7Iw@?5LTU@hiC)G4!Yw7Y z)8_`L8IW~?MngmNsogXwpc1p;rZ{@8dImkn;u1N*`ZHPd2GJ8Z=;vqw;{8z|{7sv# z5J?jD@9aeMlXy&OWzj!3gy90ZEL+m{l9_LM}?T&87s ziHy4MMDQjTT@d<2r2~poI@^(HUUWq0D`~He-;iC*=Cb|pWEX1Ul~d->o?c1udY?uz z&YoZsjX%?u_Ma%c6iMR1RbHYGu1Hn?69sCF|Eq^OsHrlX_e<>m?ItMamU`kI#b6yEA7nClnW`jZ7mB0rb#x1h()5?e#FY(LzJvbVCjfFvkGRM(~TOqufD`@vdZ2 zF`2$(hAow;$DmoM%}%6>Z=jXzaS|H3s&=@sU$XE29ASz+=zk#ET}WlsWV3Qh<(TX~ zla5fx!-|?&`Kh9!XCX~%QJ&bQ!NorxI8vxqqLVcZ6Y7s9S%g|&TV?Xo^;Y=_WSyUC zrBiJhTj)36ooEL11=>`*)|5)4dOd4)GT{kTz-DMKgjleJnaIQuYPO>2m}n9bY6{Bu zAkM@fNroVCDF_})q`&}ttWytlk%@^cmryOW2=0zdOVK6{kSBx3xJ%Hc6T1X{DU}jA!%x%;1)WsVQUED4D(p2!CN-O(CK6_E5O>L0Is_G!5Xfdh z_}5h)3m<(HBD&jevg?;U6X3R42I)Zs(EZ8g<63rIMfK}O$2Zc)m^C477 zNpd4liGGqK^Cp%1!=%*Ue*ZQczumER3@XgwWI0XTX1ILL*n3vd6scPft2p`1@7?Td zud};$Iq#4tkvg^1q&t2A-K)Fy2Ps;vf+hV)X`1#an3O3Za?b2#t>JeIe1-4>e`cSb z?YYVl^t|e$(cTQ(O=f0=hy(v1yYeaa_x1b5h58u#uIF}_&6gnk*q8OwyXTAN>X`UL zl#{FHy9n_dHLhhKV*)0EJ%xn`>Vrxo7}nh*DGoPRs}LpxY(q5eg$scJ?TLg$ff12K zg4)oH2uYl&=@dAgc| zIwhx!;^%QIS9(Xk?;;zMl+TrW4Mn=x1h07zO_BI_1Wlu_4`k4+seuMHr$C5&Nb;1K z#`fKqZ={<~34V!z4;Ir@W6yS}N;Ok8r7@7=kD?srpIYZFx%n#cS^=l{(=YQEtam2o zL#v-w#{Lt9mps%a{Krf50e%fa{C?R!P(9{~{x>O{3;s_Oeru2$-uz{piz6Qp>sotq zjqx*IX%6wsC$cCWNP3Q9+nIc!pd0j?{{`zEy{Q+*ib<;H?E#PV(+Q#X1p@)Ec~O8N zAVOkQS8;s|cfuF{AVm8V4~aWZ0Xskny&szxDhbM!3K676k0A9356QI)6hlSlEu;eE zjc0J>?`r_a(2=JD=z;qDfcvP7Zl6N zv{7b6vyPc|SE{EElc{)OU?;naUh#6Y*mzs9oHEgvwP4zXtxx5?!u~hU&~VMY^`z22 zN>}*Di{&Hzx36ie*P_Xfdp;DIojg(d?GX%EsoDaP=Id;X3|eZWXkZ_*6kRchkQsUd z1``YV3GoQ&Xwvg2%LpTj14{|P$c8l@L-vk@vfWc#14sl&nP}pKbpk=8=;~zrqTn1E zq$vD!7;UJeBYn4+V$Pmip_T&0O2?U}M(0MUpAM2Py@thxI4lc2(ZVk@LE2SP83`N7 zEtMYYbXdvIj9HivW7D}*o~JUaAjL5I8>*G`4_f&wW}=Gf*A*qYCv-e~8}i=>9!+|=NOg);f%B9LOy;>LN!#qr0-DZmkg zosx-fkfJz&HN=j9vK~6-Ds(3LJ~9L}P~p{!+sP0XkSvZa(xNZXJFC@;N<)aAPC?C3 z6=D0dK&$#;cK$67S*(!L_fI`RkbpVw><#S?NgML{EmKbenKg^>D7*96TTKb*L1+69 z-22#EUYtDk30;3&xYigF3Tut4QeXeUSu0CpwWZ1-2-Hse^i9$9Zsy-txp#A@*WO8APs>|Vg{f~&N|32%L&jD zS7HjXMFlaa6U)2`0XMp$?NEu7fzeAp#-e+f*AP5!zx zkN+8zhj)tuM-8$U;4}Y4Z{g!W+Wy<9_+sd(h-~ed&F9AAIjnh^+<*M!6m(zxL+ski zJSC0m?*FzAfLGu2e}uYF1OBny{;k{wK$|2aNjn07hQmxKLNx%PZ_iJkPM=zzyB=Ea zy4Dw}Y_(~3XT1*P4!O84`XSHt+xf_mJ8ArqziL3C(bRsx4Y zS*@l=QX-Hh7)Bio5arqE>8{=IhN%hS^U`6x1`FxCyPHXAl47_T!O-F28V2telN61D z0XQfi5+SlFz9xkxXnw?CLT%~;2*3pZsJRAVaPE$XXC~e7?RhTED#@nUr3a;z zwLk;GG1O)wUdF(V_gQ^>?5Xp`h?HCyHFOLw77Xi?9xoUl>E2|W?u`XWObVtejh86&b5uY9fF(+lkT1)=Q|6n08cd zQi!Y-^6!+2K?`wL#~$-7(pV%UwLRt-Wky0&^W5&KqFq=aZ1zQLad4sHXAp4hJ`{aW z;zxPHUk=bdXaEfa5(EK;712n1pZK?=PzZ=#`B8d)4=94y5@DkJlFl*$qOzF>hY_M$ z?i9JD3y#Bp?ur{q>jxI#cxmNv2AOesKCE%0n9&()l8~`QvcPOFb5_RC8M)%|W9fMu zkT;kDY)7A?hJuf*!{SN1nA-*-lVF+f8{C;&q(O8PxkizYapAR8WFGm{Cub*h*DB_J zY5r2aXw_oI^^f=bj!aRB|4`A>BA4mdya(7>W?xnm$4{YQ!C-AbY}GeNfuS@`pQ69< z@cgH~%S+7Wok99b!O6rrI)GaZDqfp_O3IW0Cx62o2m=SzaC(v|nstkdgW4VzpD()Z zp8TJ>zTFQQFVsK!|Ia}0zy9)gp8dzBENK}rF~P)U0Z~(r(<0}=1Xvtd{~ulF6j%B8 zc>U~}+{w1>nLN3ZZQHg^wr$(CIoUPYb~82o`~I$;o9Fi2eJ;*=t-beJ@1@{6EF@GQ ziUaA8CDHrDCPx3&{)L9_pO;33vI=6GV-Ca(^@@>YE_fCS6q?O;*!_ACq>LV4+=>K} z^#t0Fj|iPt9jlb4>X>y8$UN#$z;ci5nV%{1Y)X_LNpEyx>2}g?Hva2UDyMtu#LGx? zjj!ZTgo!ZBt8C4OtG*$vW(2OO0Xu>UDe%~eY0V49qeMexIcV_kT2T7xF3#V}{*XX| zbaueBa3)@;PLCNsop5oFtuCFqn_=UaHbY-R zsj@v?Mm(HQGohW*Sca-jrw2McogZaY%XS5_xsgPnOotTq;rNRpv}9*@4&NP2G3Z?7 zrZrk(%bZ&r(-;-9M|Uwyos~uep;j}fPr=gD#X}?2o z;W|cCjw$rFI-B{*_dD5k&Rm40M|N)0mr_dII=igfmd%{PoE`m6y??GA+u80xdY3(N zX2MER2*vqEik=j)?3~Clzb&k`I-6@tueO_dc6PM;Vx%H7Zywy=YOT|caN8JjR?R$f zFO9Y8kndHEU|xDlg?O@;NCePX?`U|qmQ+b&rA1H`LtxAxU~60+B?5LaQK(9#QBmi4 z`RAz(+OwW8ZBGv-;Gv`{%t&_}6+`VK_yTRCrCmPszhLU_ED$CNy|+j2>@gS;sw|SX zurKI{giXzu{Py+Vpx;f%xro~aDKaC)%_Jx&% zthTeWw^AIgTx+(66iL;t*{q13&>GX6qW^M-QJC8)4|c6mnN!d2cLsB9wN7|sI#gBm zfX>@%YPcBFwar>cHVAC5v%+jIv;%tC1uB2W<+Db<=GIe3(*;rSlQ(gcnK4B3l7icAHMZcYdwbrKA>APsg{Htp{sG~?&V zE7T{4=}nh8_n}~oKjeUiy~SNuT#zuiSxdSMA75XT-)Up3INh%@1ErvguZ&v=(PHJq zczPCI30^BLd2G)Ah`Mmc$>xd)!3r70YR*n%-ygb=sY->$5?kUBUmBtq%26&OzgwSW z^7&5`q`o~*J1Yj;8$0aD)3Mki*=f%o{I~irl+kGk-qz6JfwIz)ncNP_-*eq%>7y$| z3(+Z9x@4WD^s73PP#;3LDdlb=*p5{Cu;w^c+-{sy%(^<`v~&BkEz`XpS;^;-ZZO$M z_WxImO08I*ig^Sch@_%31Po1)l$_2cErLwepy!l6cRNAZ)@EUCV18t3I%6nyJ9=2E zF5y~pHqP`_?`~B^n(mF`e8b$Dbr7Uzw9>aC%E<1(${D?){AggrAKqY;GJ-#(uXd<0 zs|sDC+ec_p{@yua9+@hLhn6EAMO={S@GlrU%6MF2pb&g787W&Y(XPFBd7%goGWiTO zu3DEq5#y&)q8m*oS;64bd7edul!n)ac#422KVxYT{fBQ&;`Tvosu2SDUsr+>?go>E zF78scoi_hh2l)&>7X^xk2)l>R^QuPkK`;+;1V)x73>r9HMj|NlK~guUxrNgBa!VU0 z+^~$qH)%dVwcjX%*A82xn-pP5bMM|CUkS6L3};%kGXokYCo`j1O-{^2ttN(y>_WZ* zjopX0ARuTRib)gZlz5N#?PCWavjd3HIYZ>XEfDm2tgpM;ta%JKc3P2zj<#4zi8 zDpMk7{I9Lr0c3=^JwSaUDmZ$Y| z<<5GaGmH4LHe^iaksJ0!vUW>4Z-k$7jkJD+ZARJfX{YfAWsC*Q@i4@Mgc*w=DI^$W zV7_0dhOo}w>NgC+!((fyI9Af-hMPdW)=vdGsiOcwSd~`L2f3vBh;Bmq$ z#nrgh9rmDIoZ6X;MpTa|!ooYgT2~$waIe)`?Sl%zaOdU2SSY~G zi=NKOoD{2y@=h5AY7$M&II>1>l@S%?C0ea+&(+6Io5ZARuYPaO43RTCL-xV=|2WIbV@v-lvsy5Z#NHd%yG z7w)H^e1i{!R-)=YWg1+eoKggW!nYA4w6_i}LRIRiGmxf)gbb65%ick4S{0@pH6;yG zB~Rg^pRG%YN`)dpZw%SC$rY#uN@lZH(N^E<*-zsgq!WHsH@U!-DEix`c!#%#r0SD_ zJU|C95ac3YT9x$qp;djlAI(`9jslSgpn#lTbd^}+nWIdg4N_PfL(pV#S-DZWGC8@{6Wf z%ftv&=f^*-ICZwGBT<)4FwsnRYA9&R*#QWQI2K_6Twq+af_E`b3<0&W98iJisW)JMHnebx9G}5-JCX! zg;zm~8I}@uLgc7^uWLGhD#6CCBMe?Sbb=`7$s$zoM=7=5M4CV3)qR8<7V4f1zkD2x ziPz@xqt>N0#4Wl^0}FeXq@=3M#JM$90Q6ugNtgW(nj(bbY&-mF1k{!Ar0pAJY~y3) z*ZO-oG3NJ#YuB}2n^E%Lp-rC_$_aGXu*q1-1BooRqtoOcR0x)NKE}gTyqu#eRpWCZ zkXR9!Efr4Wa4!$FdE{BlZgf22Jr=qclQ#4jxxz9`kZ^#*qnbJ1zvV{%Ki47~JF=b2$wh-d*E zK0#lVe)?}yzlvYmQETAg0aJjJfDGOv>j2&i!^f2)zBY)TGh6mcB=Gk@?+x3 zC%X$d-|R8^T5e45KJOJcrYRIBQG+>^639f(6#wOrY6d!&AYlVX;UpaJ0Or(lrEJ;I z$Vu4@uvPg2Ia$^zb?D=kFb>WU#K?BO+WtaNS>$AB^`OtQ1jQw`sj!b4>!2lbBq#h` zOS$=8e+w3ZDQGv|h7whtuheLivC7txW>b|6$Y^tFlxx~F(YzQG*vxYhP)mf*a$0Sz zRJ%q-digUHpxeu{TZOx}n=bhZFIkuU>j^zUXm`CsD}@2x)y?3TNsXC*DQc@beDs+z z3m|U~0lmM2q4SfP!J6gt-r|~j?5~w=lb>zX^kq#dZKaL6 z(eM8#_p7Ab)CvRVL;7DVf{fTWM9}$Q0EoGPKL>-%K5i5t*O8*1A3thq@lm(PoflDxqum%?(b zj=+C#UT+f0CyfGPOIn;PHq`qVk(Nb>c6Q@TC9Cp^qJtze1t}zPQ7jifD12FHCKnR` zp_mG>n4+0PO>q0pz%dNpwexLqcQXHJ(4k1L$gA4&}9;s7BuI1CMz-*O72ZiyFp znw^DM^Xx%h^GBn(Vr2sjn*VyR*oi7bhwYUe<%WURA+Q!kI9tHY$kS;Hq{2L-EJsl>2OaiLS4OUE)Y#cfp8a(m z=9(w$O2h=rWfa?b!*E%9u%5{*x2AO05v?@m0b27$+qSZ*b&XaZw<`c6eyB7ojO(s! zzM&c)DO$N%tM{roo4REcw@`o|cmrgJa|MB-F&Yfe#sD#tzpzF|;{=6ZrfE-(NUm~IMK`|ZgCqBGqF`8{5>Ak0PU+1h3oVvRsQ6i z0|Z%>Yf_sAW-swYn@Nb#+B^>qyNCy}(7=I- zTtujw)&GpbQQRwqy%MB`w=+a-q>$x}omNW07s@$iD1?(1yqmRMfx`6Go_UkQOG(gl zsbebmw+4PH{b~KX{gc;|v%CZN;3yo#eSM0G6g&Lmf@wLF!@3;gkdzX&jEvzQ^N~#{XtL)a z_W8;iUC&o0C-64bNr~nc=>nw+omQUTKTj%L`CS_GhhjCA8gS=P-z*0<@YuO=N>yxz z6tIR?F}}^`Whd#v6iw{n(e_U4%2x1&P}(J-bGWz}n4%3BEMHXq^jOnb((#aAzTPJo zyz=9r^Tk77TQT{Yh3O#F*&>>ylsw9;)9tU&V|)K}ktN^Pr{~vS4)KgiMMb2@Ky}df zPs@T1#lY%kCWImBu_Q1tz!b+27o9@{E>4o6Y8U5J$AQn{i~c6zdLOg(W);#bxnvp72QQ@=&D}t;bz~{34eZM{o@aOjFci^OKtrXz3!i( zUyt(pBKy@iFzKM#AsPM>E$#}%dQr>FfvmrG$Q|0aIIk;SCIF8t6eMKr3Z`9#MO0-x zDKb&XAUft#2bVh0E~bkPEwzCnKdLvSDaXWNwHQ*7?X!U9xS|-yYvg~QH z;@I4A)fp;A&#&gGxstI2$KSH!0XTupRa$|DkTCkvhsV$%jCE58f0_X#z%oNt|AFXMq&*PEYt zi@V%dPt}9w|6&SXe0Ko{g|C#eBfLBU*w^R-$w!aCSMy<-iko_%N3a9WqaJNojrY8J zh{91Wv||;>`ou~SD1mVp$z4p2jEstxVF^KxiXaMO@m(vNg$W|1Xe(!`Ylb!}9hBN! z{XF=mP0HBW9)R&YMQOs%+^lXjJyJE(99wA-+(yuqJ9S*NJCCcKFn38A?U3AC>ykkOH3U68d1t>-G$N^u&pWSmBXRZU-*f_;Dt z#-xUgC+|?bC;Amp$dtovdi0np;_RwY^XMtS*v8VEiEP;VBMesQDv{z|Su=tGZZ%2Y zuYpjj&Ue6qbf|Z0%cMU*_K4vw9}-KJ2i@eS`trSOYTP z6&gH^MY8!F@+XdArTAcYvj><2V?+m&HiUo4RU|uViO261V&AE7Md^IW&Bl|KwJ6ir zDZ=&)A{cA7&2^aImqe0++#94ec5DARHq!; zWWW$Pts|R=^ukvAKnl{GEjoD&pO8|}us?f+=K4Hy(M-A2 zlI8X<1T#}gvw-#Lj-H(NTe=B8F39!tT!prCz|HyaJ$ja6?m|!NmEz4eG~(frLZM+n zqlCKl-0wfZ)sB9>h>%$Se)*_WG!!j}ScL5s2quPMBLqB zb?VLqRO1smZvRZUmBKi<66um@=N_=&e#``do_qg-djFm} zz-yY=*J^@Ef(vKkC?*vkJBox92uVU=G$$k!!i2?9(kuXga2ZDx!KNu>gWh5Z-1~9) zFEZmT>nhB05hhV>`3T6~1v`37>~T;6D8Ex0BRTh|aR=XUC`q4}BrR1r9kTzk=g=8j zXJ*Kz5|Oweb#6d9)imf ztUQl;bZjja_jUCeuDU&3Wm6dlQN89oMkt4v6uz|vbHE3T1qH*$4NNA0@idL>17kka8T%}Hy_57)`A)BCS2@jSn;E1uY81fJ_I3y}6#X{sDsuD540AXO5 zhI>y^^oC9}G(gOxE^TVF5svaE$=PnW3>LR|O1~VYnB_pcjeEqYPb=yyGo$HLS3un2 zIx-@&vyDkkOj+Cuf}@i8W+TN)!dQ(q-nVP*fN|0o@WCPDY?b2R*eyq;w6!{4Q# z_4lGf$ykzmhY~^vv_WC1$#QvZ4dNj6s8)_z^1V=Nq*-M(wUWzyG&F+-acFx+(Yta- z0lZ>QZ*vY@dkAFK!_n?4@*j=?cPT{DlIj(_})P$`|4LY7m+j6 zGpr9>++lPVnu_P?kE#dSkDqESer*cbzOQn`ywl!n1-lZV2v9?s%v)vWau_I6&Zx1@ zRieuHUp16?c2ZC<>A;*rt>LYhfn>KuB}f*z+%t;gHlfj2h>y|$CXUiDNQgp=h5s~8 z+7g?TBE&B1^e#Svgf78oV8gn-za;slFpCGNLjbcC7Gyp9J-O9>2zBXlfxG>77>DJ3 zTth)T1)>X9u}`g``^g=RFXt=0U%3 ztSR;EA?~8e+b*k+bc*voQTPJ9dsxT@e-RoVW-ZP=V?95|P0JK~}4*^}kuNjS&KlaUo!! z0|G>Z#z`oqkywgU+J`1#uwm6z$9JAu8U~I=8e0&9R8UMtwKM`1M+wNe6j!<*eju@S zeFrKlN7CH)=*9khK_-3ANo%8CA&M9w9kI>Z9DUfo>|2m}MJ`E3q=M9jyP$*S%d||* zc@y8^!F(>l`r&|Cn~QJcs3pdahT&P_vXYXjj~%g;Ed4|isy=u^`RnmLkul81aQeuj zKV82Ia@1GO*(3=~lW$ll@gj>^L zzMnbc?pKbpQm%uIO!BIu`*^P905YyZ}Oj z1E?_r8j^4<=xGFK2qe@3(_TmjaFz3ZA5KVwaJ^6>B%OE(i;px~)PXX7p_62Xc&^lI z$$S&~$RP`*Bej53F+vD7btPi;)7v^s#mv#7x@ctV5Mc%HDu~6&vdqhfC&iAkr_q^C z`qn&F?vNjA$sB%2gUN?Bl{jH!1Hl z@6h*`>BiqDVFy|({G(%jSo$dc+VcFn{>WM{*)y9~6Tx?W|L0-XT7Tl-7wdVyQ^`IB zIN9C-Ye}UY-4XTuUG}kD$-1X=^)o;Sa~|%&dVQpQ*OY~X!_06GxL`ClkpK!7KFOZk z-L-HT&0myE7V1wA4572r4h;$jmg7NQYB5t35(T{i9%oV0SU93wXGn)oIe@n$34N2Y zx`xq{#jDq}C=q)OLFlHYBH(iwsHK`b5eD;nB9h03{dL~%fc4sJC=PhA0ExmCX|{|z znPvn>QaQMjE9a@ggfwDyC<6kifDFfD!SMJ)%6Moph;XAJq%X=k1CMMbe(2(~Xe!Mm zozn`pIl&;3HYrGLaG*57k`V6Rp*_gYfr0Mk}EyG(6Fsv!!v!*h*9UcSn zWECLQkZrQ4(|btcjGmB5`6RRa&vaq;|#xPyHtc-5bD7|M&S;glK31# zl+rf9+W7lp7Rt81$9klpnd$RB_qV&=?;p1(o4?x4w^;stj^}jfMB)!_RkGvdI#6be zIHgJJzh34lG6Wq0JD@M3MF_leGaG2xO>DOjbrYr-wyMmLY!;SEPnK960J8x@urZ-I zr31gRqA~eMSZR~NFj#`1c*1o=zd^{Nz~eziKu)7Da{$EcfdEi zUZ)7yN5KQZD1}FGj5z4MnNjBcCkg>bEb%~)vk-VjA_D5H1sHx!4Un)J3{tY)D!BO; z49sk0K3*`LBrr%)w#I#`(4Owg#)g9jP5}|}4dBw1NFb-f8EC%`2yYNmRGJyh(xEp| z@vvxUl!K=niy62$D+yWFi<|AR;wKF~l_AB01oT{p(5Va}80H*9c5xwO9WdiDL&Ugw zGi3CO^1KTs9YE2$P2tBN2}z;w0U(@)B8@vPEL6}`26^{OCCoP|sc(y;NAIogG7!*V z-~0)v(EHNgJZ@N5eNnZXqDnfUmReAN%08bs=Z|{Lhj!iiM0*U&5g)?|1(cxyG?XDg zrq0kVYuhfNE0Sb{XIEJkwD?J2XOfr+4GBVuz+gT}s#O4@V~3yHkJKOV{{C*a#V1ow zp+0|&KMjZ$$$kRZ>sB2rwp^a6&AHtMY11Y$JLB8 zD=viN*-WGqS%XL2<&G^e`NHJy$#em;iS9JA?M@pk(8<_T=404eWO`)=0Y-)PIolj% z;uV6iQ?x}623(ng5k^G?;LDLV=n4=NQJ zkBSi)Ze1mUF1G*%;YnhP!(Tcy6x2rmp|17-7HSbRdknOai6zRD<1%)L<*bY_vP`Kd zvlh1Bj*`T`M{7GwOLT0iFtO@rXw@#GWL=a;p~(Uc zmt-Ume6^fzO*IsRg*}|eTiW0tbU~dgkT8QFbUVCz0{DAaD`18cAuuy5a&VHxyE#2T z$IZjX4?SGFsF~lS?=e$L)Cyw@igRb&Cn}sQHxbBaE(r4BkrH&>o#?*sj{F7FVh21d z8r>hupxqTtTn!(q%hTCIjD5inj^K~3v^IQT+_(ze(&7=UiZz&mxg~5omwG^HoULac>AXUd3#gUE{pqv9)N8vjoeeBz!*&F8;1;~e&9@r3>xlC&)lL9vXPlIEZZ zoMvr*4HTCysp3et6}IY>Vw5=74Lo22nrF`EHe^!c^CSNTz*j5G2&+_=T$Pn(#C5u8 zMZWO5wq$9kER~uN&3~s%#LyNU(!4lU9}yL|IK5X_tqQxYkZn_xPXnT1!OFV2%_4tk{3|y_(!b%%6qD;r-&lys*(o zNvIgnAbgfrlVOtQP9!K8*l2lD$0T5H499GU5ZhHLXqYDcYr2S{UU3Z_(ff?j;I#g3 zKLvfr&s`}nLMq&L zJ>$Uj_<$gC_^=TQaWb%SFjSgMRsbcc=AwuwDr7`%`Tfvql@F8n+3+HkL*B;B(J zGI^ia4mZqoSLGz7$Nac{SWT6118i;zPu-$3^CW`3S)TbXF5z8}#(K-p%Gl49Sa|pY z;($+ozP9su-j6@>0e=#9o3H9h!U|Ovc}Pl}9=L2ObbIYq= zwEIo2H9M_24PAFi6fRopj+%7cnYo%zWWTliTb{c%U=uXht42df!Yi(CTrKtd`2Vcc zs;ctyKM-N_HDMq-5wWpTkW*72t*|&4m3zj`DSvd?3Z=AhDKl7r4+yd}~?$ zg)}F&;qs(R1ViH(Jfd2YBhjyseHM+0gbk(u4kzW2 zKHVcD1#%*~i?<{w^<=7}V}X}v&)|6QXX55w_FIeKb=59zSa4jT(!{m77dB+?-R=su z+r~paed3fMJfdF0*7`17HS?-q4JNGEL$Ubap%y2Z&c8RMUxLBPq_YA23ltV>i`iNn zeT3+}Q&jq&D71fj9(MpjdU-qS*nM3zGTY&C7JNtk!nPVWmJM|8wOf{Z3^NQ@OKwN_ zUYPps8VRKL*1%KdJ-~RhZ2vvu)ZAWGsNJKo_1@t6t^Q-5&__~rn%-w9n8~&CkGfHAaHx(lJToTx8ccT_-W;6iB$97_hhzz7%9|5hGep z(A7x=$FI~evde*ex|n+nZmlpqhN0P7rzH|(PU-jpe?2yF{fyBvj1zrMx4Qc=!upcU zD$(q9(l2MeIUEM=y#RAmW1Dl+s}Uw`_Y?16W3z_ky1j;6aP)fvm#eK+AF=nZp)H@| zMwb=~>q){fi;GjhhrwxZ&8#5Q(hF1JW9$j4;utI z2x?U+3iY&I`O~Kb6Rc}VRqO{6d_J&FV3o8 zo#E5};QGmH_3djEc_>3Q{KDz_Ky+qNZ~Oa82jwN(6kqmKW>?%n%#Vu>yR5D$PnGLW zfhzxpzUh{Zt$v9pVxiyAO&iQ}ELKn)NJi{BXe_sl8~|cYlVp}97Nl@lOcbPVSV-B( z10<*Ya0Wt1$S|^WP3PnNIl>eK&jDgZ?2o5Z`z!lly;m{u;8S2=xndKwQyH7Gdcu&o zD^|v#5-GH(ph0+;)8;m0!<2;b4xW3eg8{iN!*c?Gq2M_a0T;ry8b-HcaZt1O(TMpxth8=y@NGM%tg+MGJ?osA+vJI z3swsV&+eOx>gP)Nga767WE&-5Y-_W9D=TJY=cR8lnAex;CB?mr`DT)P_G8w3nlrZH zpUI2v5b^}?bW5oId)>i~dGr|X=leVV=V!0)3D05YuOE*984Fv~`EG;$qli=xbq8g} zR=FXNPYoIj#G;TT%msl<-XG3muupA8f|`mA?L-1eOroJ=Eb=;AXJ#S^my60%j@r-Q zG6R*|phH2XF7j360qyFS4;8aTe!=^ z-p#e=<*C>H#%j*?R4P-(Qu(tp7&`(gv47aHpA`J}!4%Al0W`a#j|&0~IK*O1r9KLC zfpAzz03OvGNkH%=K=2p|PQ=oy6C60<3RQ4^>V&76&DR}5ITj`YVEZY7`ZR25sK}7Q zO`IEsX*2pW(Wd!3UlMjVYh08no2aK5MTI)s3p0umuH_ z?XXf~^|SKcW6eEn+&1pKwSVfK)7KxA@7%D)shHO=Pt*KWe`f0*I;T+V+tsHCI%590 z=l%NpXV2(&1#!fE&MJMW{n^=s9gM_9Ln#iOG0FqT2}dVKmhKU*}L>f4v%p}%j)}sJB+Ds!&w%XRU?0@VT z#*Iv7OVD{>VA> zFN9!#0V@;X%7|sMPo3XbIwrQo7qc@GUZ72Hel@2G3=%CONy3a2CL8pFLi^de<&lvl zU<3;u(3oM|dSAdnfF`R`#E~JD@f?%zq#g>qzCSTbXztW-y)9(KgTjSTE1%`9OaDeJH4#C2r-UO9@R8+gOl7Y+|VqUm7Hw<%_vA4vh||; zm{MLoQEez2Vc1CHfa&=$nb@I&s8{+)z$^qjn)o%EINHYln9vbnld9}a;D;3|{rhd| za>&E!$X40!i8~A)c&uz));*fX9Q5!BLTtjd-oFC8-caK_(+M*+J#p zV5B9fSC*8D2qHsfF;E4q`i=n3AQgLvbo%5+OtY~=XsL?r?fmY&mjZ3I8e{(M6XgUY z*>^}X`8yai8UvsAp9{tK2&>VN+_*U}apnq`v}#4Qv1nK}4k^AJ@P(1HvZ=-)O?Q?r z{4N-g2?P&$I@%Y!J*ii||7Dl%zP+;Af8i8{9KmYd^1t?>h!y)d{wqm#wv~bR2)3UF zuqo*u?$FDg;JrNpN%FNz1H^CzW5&xxG%UdZZ8&3P$%ibMf(+UovXb43Koz= zs$Jwd9iJ}zx^);HA?Nxo9OMXwsv%?{iG0LG{S`6_3dlEVor9vIAp!I&k`IzFv~&Z} z!175SRk^1{10rw&v=tzP-^D3E@;uf&7GeNx5#god3G&yllN-t z2Xib;98~d#6Tn2KAPD>v>m4AsJ8TvYEmZzh9Iag1QZTIqFRA%<}d_ zabm6by+_{19>><3h%7=+i`p#LDqA9i4E-ttMEj=?r$3i2Wus+a3agl0uoNO=4Art- zcGW7_RMg!z`j7OAl?UgDCP9@#l+ot0WsaO2{D-&Lp)6iQ}F;)&BU!HaCW-=^Bjm-ePP4{|$-tAV~)(_*hi z-+L&`fdvC1e1#0BZrRpwUjuDYjfRcb1&STRi9(tyEf6O)_(t>=v0+^JuExEDb^7ek zi+Z`uGY`6dhMUEx$EICm|1LAylwm zZMi>?D{Pikffqh$yq+FF1rd##pJ^CKn>;((P7xkvB$*%#7M*+)5;&VSRe+K{pcNcg z1sMnl4jWoL0=$4P-$xUQh0M@U!uX9)xpTze9ttWn;iiz(a18k+ru(d3 z-+e}}xHM*~P3wZS%l_K`C9me;KcjH>?Pbq?I{1sb1jhKK2_AODEdy*Q=g31hZO6i2 zM&T{*^Fjr)=eTL~(?9Rm$AkZ8NAB5`-L>~0S$ovzZONG!*Xc9T*$8r^JvyXOT=8T@ z)NaFiJ0rYflX)`(R3so}v?Agx4R&I>Q0(#A3wJX~f_wfWw_^#}Y6S!vhsMq(jSmf~lh%Qc% zOH;-DE~U^965<#TSf-r3JV2rFWupXLn~-xcqqqCYc$>D+VoKypPP^w#gahjBB zam>nrC8Id3nHT-yPDaMX%SzemiW&O+*opZ`Mphr4{jzYNF$e=MOH#y z#REw|iY0-7faUZXC%GtCxl$J!6;e984HV0+E`|w66s?wPFe>2Qh^$P=>FMX=p^!5Y zI>O3cyrV{gC(dI?`)s9lgGXi<^(fPjNsFgeE~!B)8SoObk6?EQk_`jZjWi+vbJHO7}{BlR%<8Ygud>L0&$Ll{`){JmiJH{ zI+AJ6mCj_u&F+Y2s>@()@)B+F-x!+vvVBomlqnfXG#1mzb+48&ov(bfD#-5j9SkWUm~0DFV5q5>zvh1;1YC zJ*t+0x;rrCv*%IhQtstfnJ|qU>$sVnzArwztJ&`O^QTf<&a*8Hg=xDZ4hnW#(8xnw zMI=w3>R2#(`)ET}OUa$B?zha}oJ+dC?{Y^I^g9VhvUseu;v^haG(Ue@4Od*Z-DaPTHx2 zXN24T{Mu-Q{herU^ZAeU^SS$jZIfW@81i!g9$EIcgnT($bT~B1F`gU-L-Z0`Xg~-m zCR`~Sjs#3}DHb#pIv6;Z$Gr0#(mkgT1}h^?iZTifi4Qgp=a^1aP2?aT{tUwf04GSO z_~AM%Lvq1gP0}geh7A{C2PH1N@2T7}Sf0FJ1umqHYvm<%wnb@GX38ZXJ`Hn3yIC)q zTx*9|9FH`bxz)VA40rf>Ak(L_%3!Cm~#|2A09LcJW8UMD~51j7TDYD^NZv(VKp6B8?H= zIXY8haNX67ZC9+0X{$v0PQF% z%$b0JVYJDx6-xmRBipGYYcheM)M<*QL^8q4p~K~ruqax|q6uVG1Q>}$AxeU3$mRJZ&Vic(`smu3s!7DF~V#)s@I04F?6WZIqg!t@Wky9 zAuFcEf^>A*zruS!MLbFH2>miIO6)pirKN%#StyM{ko6i^=?IaBT`?y^+DHYHX4C;( z@o3sfQjVWS7-O4+Hhqm8akRPJ3?nn^5WO;LSN0J7{RQuWUbuqs!=1NIpBDMH_OUv# zmfuOO`sz)GUt{vm{rC4eKF^Q76W5)i*H6#)4|jmG?n=>WTleRW&#}+X7jp>;^wjZ{ znY=$p0>rZY!m;1UWo=-ly>Vv>$p^^hL{N-0C=4~C4JDf`Jq!`h(ZvFa04$pMOXJAAYcK69^sOks!E3oHD*nNj&YpC=*r|uFEWaVZ*tQf zlJ$$FSznwuwoCwv>wvSe@pQ{>jOztgXDcw+o=!vB<&UW|E-b2>5Q|5wQu6!+#lQ`su^YW% zQ^3Kq;q^DOLwM{)_a7n3aAMNRuKkUJZh}(zk|;5SpI#tYCQM5-2%ii>@PQa(7@_fA zOXAdEN^%L_D$N6QdSx6bk#%2k@Z!wuZeG}>;xA)AE49uy^^=f7-Pn1!OP&xNlFFLI z>pcHORYp9#W7LwyGey6u$F#YMS*SY}Z~RjcG*_y&j=RxmXKdLs9rQs?92z}~$Lb(9 z6tYlpxn5ZB=mA9w2L}ioRcw%hForw4EV&C4D*%$SnJXmKe{e|~!wX5W;4k1XuN1Z< zu1upeE31*sW_Z0RvXVL|+w^EJELKv_PdY25O0-62QserTf6%m%f4OUar>@DNf^?lbbh zX5khB5T2w~=AuJ$(&<%a!U6c8R!4Q(VCM&9rqfLSA4g}w6=m0j;bEu&2BaO*p&Mo> zNu|3Rq`Ol>K^eM{?w0OO>2B$e?hqtIK!o{tzw;BG^{jjCv(MhwC9vzE@z-)CKi~Db zI3N&x=8x;PzT-aKly&-*oy@2ZRvGFIbO?5NU0Y5Z3E>Qg6!hp{(e%lXQ)fOQWf$gWBs-!cDPs-H zS79oESl9~$f_xn#9(|V3plN^P*?a%Je;LTiH&lnYT3kJvTTEjP$K{}3Vm7STw76~y zAsKJ_`5M$Yae9*6!<~jRtppTmwu=Rn+T}Lw>A}W;(c_>5i!ITfi-F=2 z{=FR3mkPp9?z(YZTpn8OAT_#CccP5k1Fxn)t%$hSw z6Qo6h*g@E!2_F$&Na0{W5MI#O3lw!pn`q`3u06y$!=J1^R^WQWq>%I7?s<9AOHY=N|v&Mw`TaVlVY@-s(}C1gS_BLR`T|%8}z{ zXZ6O*PV#&xUiHOJ&L2m~bn!0IFKQBS*r{%kJp7cZ=i{Ag+$}$84_H4Nx`pfe!`ME1 zyqYq-yWa0Z-|OC}OaJ^NN(%Q6$G>7G;3pf9x?*o4KaZ^ALjgpG*1e9{+ptGL$=YEt z#e(+s{FaeIg%S@19N-fZk*eP#GWx)bFv2!V>(l*lLZ!w=ixT;F1RuwPk(u}m`6=A| zOf1%D*rltW*+ybe`ULtn*;_xK!rz*hy*)Zfvf{T``wkk#!lWNpJm~}i@*1CJh@OIYn1*Qk`T-k-)gGdvZUhA$p8^mOuX&*_v(5uX0_c6Y5_~1>7=jltks++l^ zkljI^Kzy;wvhmuSV!Y*qCkV&j=DbbcE{C;SCx?&z8C3zP$=hFTuYoIXy1IP%_UqLz zVSI%4G|2?wj-}d1OVVI96C01=B1yS)5yFD5==k2tqGJtbp!2 zfk63LbbUc&Fl!tmDT_cu^d(32;Q+paCk}=MzGGpy)sy(pjN(ypysabyLII*uriIVU zjsFF$NPetM{Z0>4yaY;C$vZd=N;S^)FDp{XV#D4|ejm;bW;%AV5TRh#3(+jHuCY1u z9GJGvo_AcZsyh}kxhPbX@;_sDIN`sInK`kJ`51xqyX<-2PvE@HLTFw`W;n(bLcynR z1{a^VK5|MB?TA(o3kq{r{ao1b(>$}8o%#>PcA|XW^ZX(SC3p^n z=f{ViEeHRxoc~E@KFS~;{cDg&{0Ftz9~q8)Lz2vyD&S+j{%=D?i4iE$kr-bwVk5P) zdgtrMhkk07r3;;&E{M z@L$Wh?Tz8)k0sA33*_Sy^6K#Ru<@@Fu?qYL<*sHTWi%dTBd;{Q7Bewkcy9qbB4VxB zjQ}qqK>DI5kAAeNIb?_UNcj_*BY+Mctn}WL?h__nfZ|{{E!1J6NRQZ;^}~t)Oo2&$ z42N_C&b^@YzEd^$orG`W+FBxjiZmnncb#If=?M>gj%@O}J(=Y9gKbPyX@Id-=+#f@ zfe#9sr8_WCX=$U=ZeJlJ)u!L*rfK07Q;^hd>|-UepU+&mwRL^VMYruVHAXppuhDB| zyO;(po4r`!G){_2-j+Nn)sNnOX+m>{?8IKMjGpRsa-TKj0fPT5AIX7KwiV{f+%8G(i$E67VZM4}#ZvB*)%!Q7~9L^Hom(Yo5wd zp)i9LBhH zc9ui0=NRMcVlzmR((Ud5lZBn@_W8_~>Sc2Lh_d5yTIn)}xk;*3U-d`#Wc*1!Y2jJO zILD2^oKDYRN}=%XACA>{Ef!tuk@HX?W4t{wyr_|AoTkmpj07qwzTu{!QK^{_80OJYOH4 z#}vkS4p5%4t(~7due)#4t=wDuVIN^>8pb;(g}yhp-{y)|9p3 zmeze)Y4UHF0nB8*q~Hou%I{h4Y;o<|$7A4`9KwNg07@OtUNtgDhPSzvlB+6gk|*w| zsjnkuEqDAjzfLIBdfkWYy`N4rxjzt*-n zzmA3v^-+|%8@zcu#Z-e%vl-ExOq|V4Ht`S*d4x>yyJ61!X4V`IsN|pJFm7%$(Z1w! zlDxSY^2|0T=T6jJwSR}axw%0OJknR5e=U`XhiH@etvQ9u@AY6dizkvReI^7%fK})T zWWg7KwAgcyQfD-+7i9O$u2E#-AU$#)ds#~O!ZvOqsR6GH2GD7dSc$fW2NWF;fT+J= z@i$iAA>ZVlMEJMcO2xT?-Q;zzmWTu zS0A1kEjnEB$}NEU%LdJ*8zF_S+^Xk~LwUmDsLm9kDQjL$eN!W=!ILyZ(KqoJW!R#~8F1PK7i#;oinCC?nB>huC0`bSHqo6q z`H<7}=KfuUthuW7d5yPF>s2LdvzO>a_tfY5hK*CBgWGDCj^dQVDR*b2e>M{N3weFj z{i!{(Tk|Ru4P;G|A@hw$W=MJ{536`1`hXfB4YVc3f!UJ48g1dwFilN7F?C2Z9T;tO zlr!)hN)fJ63MOq8Ek2Q&D^76WOM)kKX4fHr7NHU@kgw?<30UsxDD{)xJTE0JDVy(N zl6+yn*Ip=krc4hSAlP$doQ^9au)`fP25kldDM>XTtN-03$zTdj0NmG;#EiJK0owjJG@Yb6C&$ssP^ zyT+-OQdf#5Yg-CiXZ30HsFEMF2jtmK?}J4mcZP{RY77?&TourY7ipgVAQgEHx?qUi zBow*0d2`mO@o=*!>TSdP@u_2Y@GTPAef_q5(c35v0|f*an%2)K_-rW#&qN)<#lxfq z=FtJrz?@Dz-{JgH0eOH`jSwqw$kzAZuY3d=fve%Y@&JI6tptlF4FhUg84!U1P@pJ8 zNPRNF0CAMV^97~iJ%==D0F%le^EECdF;Lkg@dJ0GwyE-Nb{@d_~j^wiMA{Fz6;}*oQj4xLLttp#Is-FG$JjO; ze_&cr5D_A0Pd-hIrK}L{OG1lfRpw75;cH?6rWsC&yr-wJPV3f6kZ4ltlEGf&aYH1$ zBo2hfn}9~FxiCh#yh?1c-%sO34)KbVRiJi5E}C|9o{bJ($&WlJP(x~-q4I6he}c5n z#IoA^_<(KRd~%HNpGYm%&X&d^gg;DuPKFghYgkC)JK&q!~U+gldo#g z@R!NQhyOT@o0%OxwOOFMijCw#LIA9^a8^xIJ{BBH1PkZwLq){}E(2-O;CR;Cmx1U# zG*|&BDB8XEAP{U)&P*)N3@tDOScQ?17})dD5W6f#u$=-I1KYfqH$#dqB}tA4PK8da zc0v#O?hL)eiWaeV9v~B{1!IipNm@FQ^?MiwLpi+?ftMo>G`Ob?f;x`@g&|Q_?=Qg| zvc2>|l*Soe;jO$7nuczpwqEzuY7ucmz00kwG1sow*>}QW)Vw~*4(IF%iUm~4)6zJJkW2#5 z7`aO%+Ts9LI&|)f9MsrhJPqSU+y9hYUM(S!&c$!8`9Z)g?d%ZAv5$Ohj1Uk+%@AFc zEC=6aXHEw89pdv6qfkBs1>>_31jI^;4tY;$w!IPn>KBs)1~cai%X}%g*ikn}m{0HE zAPCZWzUHIFz91%nxfPJR7EEKJXQ<`v0nE*MH{n}$T^D6-_R;tNLLP|TViJI?m6xi7 zcb+=&R0EhZeu*-_mGB|WOwt5D*q;ASQtOUooq?PhCpl`_7k=vql+i72WMh{APE z`)y60;SH6i6tAgQkd-fKy|K`+VHwTy-X+ft*g8#LubNU<93|4?3Sun`=!5`iTTu^3GR$^varE=Xg)b@Y=A#c)U~xC@^()lbBB@SI1zzOC$d&p z4K|-J@Bt{nj9)~k`Iyai3q&B5^df9hVse#Z2RtOiU_&Z2?5GU@QMxUfdE8|f+%5zK z_?<+a93^Tp3{9K(I~7VXFmHdlZa_R+0wu)~EhVFpL{`~){#)cl+Qo2GW8&$N6iX%f zA51V}9<@Fnr1XJWw}6_r;EAu~{)YoWlfB08_|yiOjH1cP2&ARjS)0*1-|&aZ76`2@ zjnleL!cKSnpV}#kktUy<9dNrvGu;fo-;yCH3r;aEJpZzYlx>tD(P!?*fkAgjRKtz^ zQp~<4w%$-tiZ4yr$q4=XWLwtZr?d1)1@?^v#ou1{F=bv9i^nzl%CYsE&+K#L$=Qx8 z@pOK>2baI@EWQ-AD}=;!LP@Oo*P4pz}mV7`Z9gMNlj&nL|r6l znM$VFX!d7&gxnIH>W@D!S+c@2vcrqBCz#9BOIZ)`XGf?SdhaK-($SbZRei$|midUN z>RNVm%er`VR{IYbN(I*%W3APL@zK(=VS42cmX~e;wR+KnZH7#CSqiMi_qi>?9UtR_ zuR8EgnH8<+3@{K39F^J~VppXfJj7NTf-R`t_3b_B`QQ45p9lkF^X~=-z#8MH^F=Xp znxiyFNup&AQ9P{^E!f=~{{F~M$bW**;qrX$<=JQb9;2<#tUl)K8|nXY?a*Ys)6g19 zZJgt)Pqx=~&|EoXGl^a>^!NPGU2eLq-V(rwLye{YK70WZPJ%@9x+z=$@rTS3$>TI} z$)ja3IJUln)9^C;0xNE0Aq0pKQUN_(`L;^hQh|bcGH5kM>~S6lp}Wo*z#1frYr$A%0J$atpm`> zI+%il^H9zyno*R@X!0a_pnd^tSn6hRL;_sI5!r)$c#4d@2nGrb6->dHft;INKoE+T zW;(2DIZ^TFcJjM3Lh}Nfe%<`AVxX(xh>{NLMTdH8Re9U&Ex3LW(nfMf2mi@r*z%dG zjLh9cp8<6;anJzR(&^pZv37{OePQFCuJo25H|8+9YcSJ&ocMk*Y2sYpI%83%%H&Y6 zQV@B6E7JW;KK}1KELazxT^sc!l6mIrve&#zc^F?1%zZ3xY~tMZ7BXntoxH~BtVpix zW?c@Xz+y=XDPDOiMTxtQ(F_4KKT zb8?%R-N(S*wIRwfde}*uMLv})ImOZ4O;%0pk{2qv?1OeprA}t#U`c!b!?Yk zEe4U8a)-XXaqLmGI!QQA4ftbtvwn**q;_bHU1T=XI*Ci!UMSj@w(#X&nMY^nxwF+x zQ4@X%qKHuNG{y1!++S8v*}f{uea#=cI|oVD{lz=u@KI%IAuD5l%{S@sao0QfbIse# z#fD$E1`GD`ly)7%Q@{Su-NQ-%Micghz4HSy?}^hOV6$GaS_n+U%oTquZqPy#14j&? z1IY-8)#6m;X96I;;$tM^(s=Y;aeAofi)(&)Icf17fX9;BuQE}@b2{BhJfiHLWpnQ} zWZrz3Xm&mYiaZGvXHT^ODmwW}tSy{++L{^*wfr0}Oc*pPssetvqhStVLMIatG~ zGkFCPUbNedE`9$?(IS*X`Q}WZ10!r<<;|h%u%7#&`{wq)e@%~zo_sYMm**l&{@Azni^zX@ z*@K|G>xEK3dGC3%{X)C6J2L`+bAN^zV%Ek~g_j2dbqE!O5f@R+88Fm@Aqjw(5^pE_ zU=!MlV4ytvQ*1P}3epTbxf~oA47in`MbPgfMtFh`rSsHLwWon5*t*tqcJ6N#wAM>V zvX7jyNxK0{krH$K&a_v?@xfhI4L*Th3A27^R|VKof3+c3oYoO2>7f_5zM@>sRXJEc zOX6>xw9X{+`|V}LhYGl4sxNV4Qs~LLt|=hJZzBkKfB%VjG45}qZb5dJqJMhb-JN#* zaWJ-Y^Y?__a`)!_^nHuom+tK`P*}DF7_oLNZJ+vpk5uYs0B0f=yC0U|3765ZK z5P6r*Ujs?dPa~#}0)zlrB7#wk&GF&H28>_^wO%|zO)mfR@?itQy9>RD0>>q#HZ^=8 zv|=TuOKzPpFmcLwje>|SieW6h-QhAF4JF`Xr`>s#ES7~yL=UA4ZsR*k`zl#87PUQ` z^@d(tgrab4Kepi}x5{Rt5#w3i^x$^`Jm#@9CxgGWXDKcc>R6wjDPdXS-2sY zQ>VD5b#sOy?3?RNBKMCIFj&I<_vV$$uE3NZ${-I5W5u+h&2?=h7SG&0|%gsOGE^k9mVaL8_?RAu9?|N@Z#ZMNn+z=ph9>X zk7_ey27nWcz}ZbNMeWq)L@B5^n*M)SAp^^elsTHiIVs+n!{&&e~iq{oRZ6T_hA@}dl^}f%0?g0 zY;H{XeJzYue6;V91V5Z4%{eJiuBRwlgJE{oHtiKBY%->xtZ}09L^X{-%dvzj#{9UR z%}G&OC4o(BovrY=y3m1>DE7C`>YTi;-2ET@0GQw3jiBNt-Lmv&P-xc&@)k9gyv27O z_TkZ;RIrlh{t@U=KoZ8+0dCXY5b-^nIrxh>O5^z!G6DCPw7}z$xTrcH4hzg=`0RJ6 zUQ*R!SZD%+S|vdqv9f4>yS>mx*KsoId$k}2^$PaF4;Bh;8W@53PZG?8A2sRYJ`>Xj z%egx^vMvri*0qilqe%uceF*XknfokF`%;MQWwBNxj(><7Gi za?8ABo{7A_D*wFZ^;s@OXH?|@nt!Fup+G<9XD0)TUF0QlbL!2L8#PzZ#9#FH=`nN} zCo5drD|!evcM2m*LHIOPV?G7)&c^(QUMJ(fdO$Cg7NrQmZk-)N<*s3 z+~-gqF{YIIRW0@qpNxEb@d$&V#7Rva@8j3G%>6Ejr!Pe8%x9gX_PhxrGc)}=ha7Gh znk;8WH0T;ybxwXusL7HjCpL%nP;b<79N$zp8OW8j`Zj33PYiEpjdM4`*9-aP;8Lah zsLATk-R!AsRbwJrvC}@}LCyboW7KEU@-UElx_hcl`ME>GoT2H>XXMl7u8D8oegblb zzvf3Guj$?&$KBBF74c&Q-jgIMxTS);VZ7zOrxX1Rq5jLCQPrfIa1i;kX7{*DV+H?ndw6cRaMxn{%H%+ z=j!A1uUsUubAN(6>bAvM@#po!^f@y3%hP|M@B@H}W-}4;Tqx|YA0w)50qmrL{A7~= zJkW3ns$d?9-#@{P(Q5z4MESYW-kbNbOit;`YG5hy0!AwueEK&Q=J8i1kThqR5!l67=?L=@ucFuPpQD{7;-N$D~{=JZ0hJc!1g zJ_}B?zHE#Lekho(A>0f-N`O|%3=j~L41f%Z_lF_?g$jg4<>CFfv=;edp>`v|7Jj5? zK|kSpE?z=32b>mW^=Xa}_||37QSx>#`CjAzX>h9*6rgNM%9(B(X%Se5ZVbZTQ8c#W zCk%5#)ha5d`$6EHF{X(Q2=BoGTkRi6Dkw+`x~Byhe!kc*x~h%}z~kZ{E5|`dk>nLB ztXk6c6h5Q(<#<}~qYc+Z+d7+1XVr#RMJ+qRYrRg6HJU)27^h>_{IXXJKXW6 zWH@H8ai1VIR+D}c_|oN51ik0-1A|Ya z3&aAulYidc-x?kww~_z;`|`IwdY^dW1`m!iDDr87Yq6HQieihsE=!gULmu^XYa#=S zd`Y6Jw6prZUKCqDwN8}(WbLF{?mF;jsk=cz^Os1Pl){f1GsZ)~4FEE?>gi`DtHJd@vEc_&G|b`1=h#5E*m~Y!BCy1H5RVLCi&OYIYmR-bVaEyn!Ih!UyE@yNsbvJTrNk&UIG*yD# zZxnSnW(*faitm2AJEtbik<@17jteijomHMaX+Ndv&8*~4C#9Lxa7Afud+QvyPJi%z zs&fiVBZUI0j$rwRj2MxjGRWEOV zF<~4$i?~#Dw$O26j(?@ZPOVY^jg$m@pd`-$21XWeSAI%|l$eBG`bU#ld4dmvdH)Hj zJX?%@aqdl^DNjf0%vgmGMvX@s}%I>?j5j5Wu`lbvQw&L`y`(C2BST|Rr&8lyfTf}W*{jlzm-K?UtZ{1LT ziq{k`J_$+H(6RfLhAxRqSA!ZK^7p$KNK6bG^hq+Yyw<@?BdTn)n@QM>aSTG?M}xPqf~fFZ+|>&pydNKgT`R1dBRe`}p-z zZed(>z4f;>mH&}5bw+W$LZTjjw;IoHwO<(#|(Orv-kHY zRg95aA>wy4hI<^Do0g3Vllia!(PQ!!irvP*>RRV zVwxWZMG30^x`;tFk#%q|#8i|)Yl&A#!?%HxL1OX0N}=`3Ew0n|XKbtMVr(STg~gei zpyQdQ@XT_4UDDgh&|0aHI6oT~ZA)bNBUlxG@HAy)YKgGtFQI4rz`XW++-sSl1s1TEGYBKkSpC~O%Fo)|-xjWpW4he2obl6##wO_q zIIpm4Y+fF3_^g6;oV~i+T^BgkWn+{3EBsE7AK5>>#|`d{^@H6ick@S4XGPld8%XWp z8{Dn_c;~R5E67>)tB?;aVc7h$v9DShSF|}*xm!1#I`TG5@+$aT4eDs|7}v-LqXH)<+=!>6Vw}EB5rEbF z^qxUj7`Qn3>9Fz`hQVUfBHJ>k4SQo*))0vfB#xfA8Fr#Gx&funx0(uEZ&SRHRdwGb zj4aO-?}Vg$AOFf>&1W7;Ag{qgALglko{ybZ+8CY83v9ubmJ3%3-^fa!wJRMWPF#(3 z^ebexE7Dd{P?(WmSPmfk@k({rajlbxh&7~uMm>q0{G%=}gEkwzGQI`_K1g4GoU0^+ zORS8MUTJBJV{3+o`sOz{7@oG*v3Q~ zK5#KvOk@j~1QH5pn9dCmy^e~uekINt3^`$SX$*(yjUs>q0gUs4F#rWDUmlC-=-Ie} z0JEX9tOA{zu0FtiyNYdWR+>4geHz!xdIHi=i)c=*EtwU|=x}nSjn52oaK=QUTnpZW zTVj4nCl(ii$(0e6*fPpx@spyjr78WNV1H9xqjg4O0cz1F?c(@dUo!Ezq{PXAjzL8|1WY6;0^fzcDf=In| zI>!~Bs5L+vgo%hYka?zw^@4cF!EsyorkXSeE&{NB zRxy(7FpwVKx6wo=86&Ke^F4kH?%jUps45n3>bpn`!MM3!*4X~<8nJ+eAu4o{bTp?W zQv?w~LLwIM+B0^hYRB@l`W>Nb-_--@3I1DWIOK=o57M=5amF~+44&co%KeY)(azev zvm*u0bBAZ@#+?e$r*f@n8fWwRqYVfE$a~ z5;|Lnz^5UP#>Z#Bqm&v!Xeaxjih(f%`i3BTYEqzS%jtTb%J*5EWx;4D659&`9{XkE zsQs}$-+!8Uami~csu)att(?RN%We1RXoLOgI-SLFwQ7D<#=G9E?SbQA5yz=^1g;9% z5|z~L_5L|9^3>w)Al)x&dzw?)t?~Ogp$4_4Nea^v8xO_Z}c=kPCfIObRZdeC& z#{0}2rnUw7WJA)19px=#+D~K!;*1=yPpb>g$}eM2?C*p0xl$=~RQ{6wv$sEMknX6k zZ@LNjW&xRUdtu}tv+%n^_leyKQflKSVMZ=z0mpEMsoClOwg8k^V|I3rCIotwJpvvGgJg4{rj>2nSbh& z-L5nReQ(4*nbPpS22E7!(Q7$LHf8JJ6|#x(@CVrK#x<>r(%c)JVew|@)a}q;XaQCL zg}(a4ILTT1pMimACD6{NHk!hFy-C8e{ojw~8Mf}!rH=M&9a{7ngs%ES#7*^IUG(S} z$dk@VE&9!y&RBQZ**WLyS#&J=lar0FNU1CI%~Qyj?Dfq|&7=25notROjGNXul*bj> z3O7tNE}uA@K1sDS^EsRvBe|-~qKu@jS-FS4@G_(Fv~Kb-SMtp>aSMpS>EW<6C_D=r z#;XQ%{tPqygacp}FuQ|Tg56t%YcH_b^(V8u_X}VO8GPeB&!>mV`p#IQNHpgP&c$ zF7`k;rBpb_i*3YX)A{;~)35PQ6(&C0F6?K@lKS3w%>tw)uQe7pTdJ*c$g~gN`b?|t zho0&_xm+zF{ck5K&mU~`^X!ru(!2mxdMcLCS_fdgb1$_;Ix)L@nwC6zPXkU*&n~nl zo_@e|LY0fMhrq0eS6`5Sh>==ycjx&|Y z(*OOMq+QU0^<_?$>FV>($(h9|9^trI1AnVOr^5B%sz0A<4N~P?EKKmmY#6T|Zf^{n z4+N#1HMGZW*{wK>rm-Cs*_VpS%GokEv>VnHJufnIx+^p_-f90A3Kw5)_gxi(+Mf5J zl#X4W_o1L1xtw^XxC1oY*8fd8KiE*LIC%Ptyb0^hIe!=I;aRR2h$7t>?xaNjK=9q_ zJO}DD*7U$aQY|5q0Ip>S;%C>oB zx5!mRjPK(w$8F8?{xpkJW5_1b^WVnR#;b?n+^+Th`#X(g1BmVFczExUpg;02xK5XE z^kSC&T08Sgj+oH0;bfqgx>!%%_fqz;3K(~ApIAb`2(yf%26-Za9xx+gtF4JIHBcmM zZP>GOu^NB|<*||IjgU{@AClLK!@pJy+lA1HQp%gnVwPwP6+w^F>(}}4bu(??m{A)n?oG5s zgTe};K_M*=cqph1WEKwH47fuq?e0Z2;CF%{xkT1K5Ji0 zMrpD7$yq@%f^2tOw4r^cd4i>-a`j=&Gv=gi;--GUhBOtlT3l7r-CZS+H~O8`+DLDo zj{&yKEGa!2uBs_iKI%`>M#j@gWB5eG@=@EdLMH`8KP{+}cR=CSi?*O=n0n3(derS&@QVr-+AJ zL3v%Si*7^Wx&vv5C6o4t4^8DFG1)Bobeh5&hur}_9bNiHzYJXLo1eNTw}m6x4ZQ3( zPn31vZvL7(JXD0^>v85*uGHgEB3y&FRF(464n<=c(S{_HAS_R>Q7?rr<4{rYVe0*_ zXi zfMI{dIp7{$lOne%a5;)Lw}~RpaEXaN!$_K(Uvg9+Qv(x^T_e~Ycwah6cBL}eI(b1d z@ttT^qDfme@5xapQ}KkHQ+n{+$pc0D<;#s-@9B+`jfLDdwwt8Wk>efB{fjkG7G9e* z8A=ZR{HGY>8rd=lK$Lr;lD2(Q|bR+y|ut%pc^1*^G zKTxQfhHJbpHJ*}+3?-EOeUIvj1>q0yM^P)%be!wAKv=U2TUzpuFSHJ|y`&F0e}~_bu63;fc~cLVww-_84V!SbSK` z+q_kq{E(UM-Chy>^W(>%6Zdya!?~jwM!z^6M9x}Ra4URZk>55Qk*7$mC!>w-jMm>9 z!(8coEzgUA4~I`pG2IGD-4!!Pb;J!pu=qs`gjY_558%K9q~f`tf$@^UDc`^vIpE}k z+-vqALM47cqTk3!Fl`=y=DP(x7Iq-SV=GRNRlh9_5KauR#elG*(LhFyFU(OBVmZ`o zv-9u~LeDGBLMf#zF~D92Ga3uEra6`X^5qe6d|t>zm>AUwPAOeCHZdwHs?f9B+ou?> zpB@{F97`ZJ7|Mo&6@h_U$Rl;sOd9os?~4~I#MwfCp*XvKBYo_>$wC1l z>G`i9{q*xk%m!h+f5Y9AB8f)}?i1+PRmmwbs1i8+{^Ib&?VJ`SV5-a%FEK_W^x00T zX3U?*Kbm;z>=SflD{vN8X}fG#E-oR9ctv{o%&6dhk*`C_-~!z6J9%c&i7?b2G@8gB zvV=T>SQOhHW3!%6Y)mmp>t;gsfu0FDJ-w_kBQz-tQ*x8|cvNCC7}Nt*L@)%E<`v8g zO7t5QHI0Uc{WBBk1oufj>I)1bd!0bCBddZ^*6gPEcr@BI+M)A?a8R4Q`(@>56roPh z557Y?%Vtd$Q}-wpNxIioYsn+GpHaS!r6w)p={e(dc2EUGh)uKH55`N=6nDmI@g_H< z?<40`c*d#zJ#?BO*VorGIv2@q+3v5&f6o#9J>+i7^}o5f{xK@NVeERumx}b*s5`$r ze}%Mf-tt90mSQrQms8;(|3>c;C>x{1prNba>P@`V0i&?T5U@nkf_fz)LJ70vCgK~r z+-@?qg!#2PJ6_;ubOwsg6q(AsJ~LWTH+B8$OHGBDI@7e>^YX9Oc|1^KQV^&YIkTVi zVa2Oh@#>oN0~IMkwHBtV{FyI^8PEZFf4=&W=bP(OTQxLL`4g1h&`Q&DMV)Gwug- zdou`?RC&}*n%p)0@H)0}9nZ|)+`ZS|t8ekY=`dInbjUR>Jg-~$FBGm`+@9DdqIUGV zp(x$EdOtH(X7brzIGy#M@)Y%+jkdPf7#*~9J=Gl`&mCG%FY*pQH!;fOW)0B42?8~| zfXRV~hyfwocd9%u<3?a{m^>h;5=;TrTumK25GA0;Jq;&7K0u8y9O2kAfD;*F9ZpXR z!~p(Vfaq6L4>+&#%#+u zou~bi$oEu^;5;(|Ja40yVyCjkc5iOj3`IZ6^F&MYbR0;b!>4AelPH{i2TF<*6{1EE_OyzS(cIv+`~ zsXlWsYW|)h_kbJl))y{(Aqs#2&HXYN30@0GV9+oOIW~$7X^Eq}kZK+wRmQrST^uTj zXc&XRNm^IHl+w6bO0THwdAZ<$wy{ZUd79*VQtf`ndlMNYtmLl>l?z7G>O>Ma3r1ZN zHD~i;n=}Q!lD;l&ml16%$}L-+NQ~3UDTv4GL|yQ%f`dprAg*|DZn_{Uk_ng)aS#E% zI?M!v2qTXM#ttkH!-i>LTcAOCVGtA|bQm#A2LOX6YW$`)#byt0HKiE>1R!WR#Xlu< zMn>;qK4OE^VKHSr)`TUj*hTM10!ax2-hqPPBnRDw{OA1@1C$4Q%N`Xeu8I;Sxaz8! zVl%|b;gOP72v_(yAvDVhcyqc1(U>2OU@KsKQ;^O9ZKC7!Q&rHWMwt<+KV>D5~yfOdXJu zM>S}we0cTQa1gvE3ROeJ$v*zc!pzxs)gt(}@XJ73a%EyuH6y!l)vBG{68ltT{j|4x z71zp>wujwS2hw0&QBP^JDYV+3ORIwGoV;x$)aRGsM%m57`TxO7=g<34u8OFunQkcT z$ELnM&eSW}tpA0=6E8!+nOW;X>+=W?D4Hlo(BXEXyF2Xk74qMCx4wso65w-`Gz!NV z68SqVfpjLkGz4N5#S%7Vl(vlt3fBWOqsoC%#kMr*QLfQln_;%7M9++VYG6NRErEVX z9HWJ}Bx+F?41gevPeps_2e#D@z!!G|y_0RGD%9rAL%_{a0+TT4MQC0p)A~)6ZsP}C zq}72K61(Hmd44_=H~#T}&7C(Gyd(Vl4v1`Nawvu9vcI*lQUb`Os8uD44GEGP?!Jls z5i^--RF5{dsJ!P>ZEWo^4+>=;TfV!fzdhCO@3SCHpL4boS?RR0{?sZE)q0V=INzDW z?0YLy942K5I%!v;{4P5uwZhYlUEG7+=xjRA5|ymTx_3K=Iy*cXU9<_Zovyv0-p7 z18yrAh{3F{UDB{kRpSK~B@bC7YO1oBdKp66g^ltG6$L0C*n?%zOpyo)ZgpbV|1zN_ z9LI_~T6BG;($ttk`>oynUDf~vvvN^bq7ZDSo(y}^y}Px@rdfUE$EIq~V-8`i!xwJA zrU>7wwB}9wH|e>sH86 z^(dl$2}+F>KMsH47#t$svSuI;h`&scBb#g(kCmLcT#%3Ua0mA14xA?ZlJ#14TMSP3 zB9TPwD@+$R5#xf93MGyi2LcUa3H#0oK?}G<$i0M+pacL-y?5gbyU>5L5yJgwurc}F zZ^O~(jssR1dPODnzzFChg9b}w@&A~5tFShkuxk_v7J|DrxI=I#P~3x4io3fMD-?Hk zcXuuB?(P&QPVu(5Z{Gj=zrFXIJdrt?YqE0BJxd1j5_W2;Gp_rF&x)RnR&4F`T&6~} zd!rD-b=*QvglieSwmMt$t|Y?MW#_qi2SXDjAxuMqvP2klWDT0TrQkk^r z3ob_2_*~3`lTeAePihDms?gp{(R6;1bZ#ytB4tzg$#H02V_8LUk<%J=BAv_ugMGq^ zfhv%Lm==}W31MPM<5uTRxPv$ol&S!QbysMvl}z|7i+xd)(`Fj$MqX1ZVJ!krUwY0wn%^YxWg;FsD-#^B)!-UU{E}%;koBgtugQ>!PD)dRZk~kvX zn7`X>8lcH$6HwmsYhQL>ni!IR)0vU=pQ&(Pk{1l0djE!<(x({7MpHLv$tu}jZf^d( zJ3o+>b^D?+>PGp8RIEg(c9QAK0GW?FZ(Gfg149`T!=&9}(M%Kji?7p*%WHMipO=MJ zwf3N|OWa;zeV{vG{*S=;hnZThIS}yE$gz`u6zi^nbrio^Ue>FLO#z zH(l5_7qhqQQ~tX84~R1<&pC-h2+AT3#2FxyF2oiSM-~(5{WAcL>dP~f359SbqPhbJ z;(5Zt&}OL#lepjvMGawa03h~_+cRBG=3+=5XZU}ohY3HFyEw%V7eiPvRg~H3GZ^|B zQ7)oQKLoT<+CZT?7;mv3WLyI#Y$W8EkUAG}5=bv@Dj7g3&o8g69WFT^MtL5)(#03>gy>Q=+|(nyQx-zN&HoGfheoUC8c9R1J}KdH2r*d&r{IiBGZJ zS3b$t)IK%$!y&&k*Ly7gs--DmZoB|Pp5^cN!@{{AEMd=+74`BC>?io$J}Z3t__$V@ zv(=)IoIPH3ce&?$^!o5rsr{<`kYgjD>EmX!HJjh_60CXNYyo76E)NEPF zNH%@j4gVfDGg!jS4qNVum-bC4TT24PEtVnnpo*6AO0c6{L58zj!+E)`#RT<3j;7Ah zfj-d)nuB)6(d0|#?TyN*K~LsD3U}4*#u4O~Ad0it>v4qOrwI3o@&2;v?nE*av7 z)d*+kMuS0xDDoL%gPRBgg8?ak3zC4iBI3Y+6(EEN18jVZglWWo9-T5vv$a&h{9$0k zaEVaV{fz&BnY#|zV4Ue>*#r^!*`4BzgBYozY_b4KS(G!d9$&y9G4X5;uK?ClT$QsG!pa0o3&UiT>vV6ad zU}v(QKUFNIK}#>k{doiE_eI4k*>$3Kt08@eyh>X68?`tg_6mVW{73>#RqN5^I+ynk_4cqj2ha!j_bZBVSEM?LV;)g zD*@{q8NFN_l}=g{YEO&YiW7C>iH%-_94tcO+INnPdUr{CvQ!rThr1+!G?s!W`=MkVP`;~U*A0@2OxMz z6u`&8hN-TJDSNGJE=D2F{UzSwyKVuOI-}#2s2OGGq%yBoHCG7qr*dtv)QW)zMaO{K zmrNVHXwi-~Ydr$qEsf{VlTE z7ckccW4E0cp^pe-P-xSJyijhIPm|244e+s-K!66|QdiICePweW&s*zf>_DlBvdzGK zTXOwSDq72Z%=9T@R^aRPPe)^njRHL!zr`By-4>Cczs&RH&MrpcQO;z=69;B%`T7`+ z)*h9e0-K4V|1w=uk9lpGqi}2T*$10xA~i>J+d^&nL+%8ojRtZ(tB{Z~YHPsOB=A-4 z7>GG(Q;j>EPxJHqUyk17Y<@lYR-d4zWNDn$)HLEns|inXl763LNu7~LC5jc1BrrzQRD;-#eNzXR?Nc_n6#2`7L;Yg7 zlBZy+kIwZKSdu4S%bu8%I~{lTBV{yApu-5EwPqh;1sng-WD=NqS7$$$xdf}6{*W7Q zYT8Dc1f78}jkIx|589<3B@$|@HbkfC@0D_a?ZVy1l|!MrlF^J(+($!huOO77$XK0A z+^)Z$>XopgQ(Tr`DXrHh6Ta{#?mi0eTJ8FF*<5PgFSADpm$3gut!%GPCKDw`n08x+ z9a-aq5pXZj ztAuDTLr2uAusMlT4@NiFCU~+1D z3={bX@jzO_H1&10zV9fF-@cszg z5tRr)TmnTW5s6&aN{qc6VqDV_fe5H@+wfqVIU|cAr|%NDAWFhkzOO#2{?!IycCHh( zilC?*mQUckiU)R!Utz}W&t~lWc%^pgf6`-wxDs)2#b6BBotMADYrJ0)0WBi-yXWTfE;b+%+-Ii zw9XN$u-NsaOhQ(7Py&?>z6&PI{AKzOaM~M=C`;S#WQ>j%-*D&4C;K#mgXhoMlI^Q| zk#ieKNq1`wg27ZM7X)PsLj|}eRV@_RNkQL;C;4FgC@3%ih7>2pW!eeFhOJ;EbEH<| z(E?5aeU#3I^+3niVKbZ=YK}I#Mu)r{Cxv{$1Chi9@UgUu($ZKahvJ zOOrQm{V{>-v=8THY;LTcD&c35Kw&Wmp%7=eF#D=Khx+TssCf=$E=U+LK9s1n&XAE9 zCJGD&-qF$1`p3x)=!_%w;bfzyFOzaM`|f>z_0&G)!RNBM4`Y@tBTcJW2N_eB zEr?{+j{>NP-iy&5DZYYt{&w25oO1Fv4%sFGS0~;i3$Oq+(c~-UNO2HS;|~RKR>YmS z-$2w@m@;a}C@0c~LBCcv9?q(gG^QGOJgi-QaUueq)v|LH(ZLoudW`nGA8J5HLrn1s7CTpl} zTFxWfpwc!$*&0+j1rSj|-F?@T61tgOxyk`A$`TTicxOlNS4)lor=b5pp(pls(o7M) z&C7ZFti0D9!=CIs`6If~`9LIxh5w{bYqqAjo;3+&F=e%#ZPde++D9o;1XnQA&PWw< ztnqOAUgmGMdP{A?sEymC&BH30uf-1DTWix-r~pYJa~v!}A)re^TbVW8zd)kFS4<^{ z<5_Rs4K3OSq9i#gU>XPjfTd@DfjMLbLr~3}tRI2MCTR>%ER*tT&tIC6mV}Hwa?-|oYm8*9JNqH{Wxs=6j^_g?A^cn0@R>Q zVoD^PP)#0ThTBs9Bt;^l%AI!S+blgCpYSjQdAB$pO1BFRs19poxty<{YYwEk#B28i zkFheff_{1e$#GkK;khRDPBn(=GcDAYd2_Y(=k-^XlRAcBroksYSoRMBYNnFQFkqC=y_OyjeeGyhouH(cvOe5eYRVaVHMyw zEyWYt14!?f`D?_c{duN&Jv;o%RMcE)I0<{9Sh(dsrYD=2{b(I+FX5-clao8oPO&K_ zVB*UmuFWs)o*}1>?|W}OuQ`#BkdB_WQf+G;P)R!wUJ5VW97=zkeQRh0)psXPJ?a^Wq6GA#nwEii}#`zC(#l_)e#P!C}^qCa-6W;sT>@H>(*@-CQV!;ru zX9#of?xsT-_KTK253r2hCi^>*8|ooj5=0w@WGYGwA>+`}u-lvPs>yf_-**T{70-S9 z9Oqm=HYI1ER#Xpk5i{dYR??vO)DrCxN3gs6Be?rlCa08|UEA2A>|a~^TGQm2Z$lmU zJuO4$tIf9x<=M;2Ta6BS%RK_su37xnc)XIT6l;rQA6dk9}GokY|Ak0u`{qW%o=xmE=E0qbuw zzpjQMqVc-p$rJDWREM=R6#AcVTEa5aug`}nt=fyYT=)-@Y@NUM& zZ6+W1E|Po%rN_NTPJcMa|38-xTO7rr=R&Ox=ElQLR~-(gZ&$C4UERPa+^hLQ-{-%H zlYbKb9Q*%4O2b633T^$Fwi0-p=P`~D)H%4y0u}AM@9QOj!ux&g_a>X<^$+V^g^xn) z#qBf2l}bfRjY1;~H-d%Br^Q0Fpri!}B4Tm)*Hco?m;Vt7Fb_n4Ms4?rk0aoSZb>Y_ zV(Z!_XTqTE1oR35wDv8+7~SAKTf+jx;Zp=;itJB+kBW5i0U>h+nm^dx`ATKGoXkm? z#q43N#{#yBm0Ris0ukYtyr(LEkaFr1OkEH0;n1D2UJ!1|d9b;z84Ndj3$@UgiZ#Y+ zt~8=Cp5Jn3v2GnU`Rl&iBD+oUU9xu>T->MP4WERSa8{X|l8n6me7IfI-g{OueX)Nl z>w^J6VZ~tjG?k!o;`FPXk{}wHtf4r5C5mWB1-?J_0UCy*H{X6+_jF!8gL)5xSBFixhp^t=#6&x$JM;Zm6JI2-XPLi zD0l7Og}i}g)5%2jFOLmL3GXe+J&!6~hdtr9o9N3opuUHg<=qe?F)S6F-ylSRA`qUP zm+Lo^IJ)vGyB1Il3oHUDgz1B!C8R`?4bJ0C0|ikaqZ87?5$5yHN1=WsDJhg$6BPla zahcL+Fds?OF9=LEG8XVmaDna&=YM?IE0Q-Qp$z+IFyjrVIgrgL%QGFb<3Y!h3qolF zm8TEKBM^DYut@lmh4~lv&FAPFGa|OT5j{_jj?hWhmgp8rzIW_#u>L^Q&uWRZ!URlg z<@z_09S5HV>laXdqpIhAekj44$=wt9x4CYz|LNs;4Lufdcd-BPkW7z$i8hGFQ4D*&(<<=u!{tw{H^Qg4omAJ-(9%0o)$6`R zne}VTp`p4n)aS+R-(yse#Xj3<3NBV~Km-mg!XBCQEF{fPh89kV$`$#52*c42U|z7! z;v51uASKZ&K^uaI3?U>yPrxA@i{mG((AZFEErSE2WBP}QlI~u?Cry0nCF2r-g>3`L z3NEA&J7ikakZYeLr}7Qb%eecdBMG^H9$iqTy>%PD#l@)$lWGg=h^kkEmkxpPANN0tdpgf8d=Gvu zb9yyuxcj~|*`!^Oe=fhClV7{szFfX}ycF)K>dAe3-1nU-f6=UymwI>q)h&UiI5eF` zC=ujoRLUWuR2*tMYv~j zRj;2u%_tf?>%tqVgVCWUCaOQzZ-k19Gq(2Fs3FjzJ$iDT#NR*~(1mW5pMUTCJ*A%8 zBF})iy-qcBiEW2v+D$Oj%>=g~Bh7Yps648|;%990Tk+@@_Dw(}utSa|k;d!00& zXohIz65@>rLc*X)JU`PuTr4QB=qvyk5nz;Lh>mIwBhpQcB>M>lk&}DCi4KTVpd2N* z!X%PMIaEgx6NyDw${rXAhHWo_IPw``MI`e?w4vgzk!HyhmO;6)YaSERvWXEqQh?fR z>KZJ1S>lSP*NOZ6ZDRzLzYXb~5r-xE>X9h+)ol^x-$_^AWdy6ALPzH#sl%1q$BL9G zg2uo_yx4xfPNVk2@`Kc+VIse4v}K7^H)7$P(g)8qgY{vx=9CP2|}WaW3i$}~P)5K?dNC_Z}JGs3=^bY363XrK@(Ol6S_ zJ%UJIuh~5z96m@v74tpv9fYnUA{xvnHs6bFBr*rr%OP5v7lyD#4ey*bFG0}N@u_G4 z>kF)N$KRv^B~$#+meC)xqo@F%Gu7qNnU9vvD$(s)pU1OH zvb($0`xT5g0S9!9I;H3G^%;ss_gCLb8{JyCZCH&$$GKx3DhU{0ycSQK`YG>E&peeVorUfw)6 zZZ-~nO@Ggmxy`Bokt0TtIgZsVB+jdSWG&>BQNx`AhcZu64E7uT82f5FPDR+igFG;c zIRO5{*!xX-*t|{#$R&a%$b;%Px?|i+e;iOmZf>8^8pjN(DMS#;-Uwkuim1EdWi-3L|<%ZP!iu+Lp!TvxV=|_t86|_1edjsQOFokBIF9B z0%!~>Q<3Y@mW7gGi5z3%MB|2-!{+1rCXf`vdP*Zh(vC^~vNPJjWRS%3bic^3xuBa_ zua$R62$(q$zLy4ONhTNyeg?!Lav=+_Qvi@70%;jXq-o@+ur*98m6vR+ieMP92a{2C zQ2qSFEDjhSU3g4aGSv4TpSz>>(HK1&ODle)qx%mFL8~>`1J#`&QrZz!jnqV6pdhn8 zy8}Gn??3%K9{qEZnuT4T7l;dPwl2~J&&jM(c$_YkSg9%xCN6D{ei1#{blhcZviH2) zl<8A4@zh`j<}CJ1A9p&uReyV&pslYS$|k-i>XC$qz_WX7@=NeiaKmuHQh3-fd!qyIrbr%eh=$vAw1ZZN;(i0LFlHhHrkoHz zNLj$C5)K9hOmhcfhtZEvNMbh}liFno=~I z!_*mrPYky?z@NmBaPUHLV8!=P{UGm+0wcmOjNt$j`C)lX!+`vEqA8|GF9aO6FGZXh zo5;fj$4QQdEJ=fF?#K@@3_}LMy)cK+){6!p+dp;BFwr?*RwW(jo!D>7=q9g`+x;_D zaLaxP&_8Yq4^NTWD5!*ZU=Nta2u2nw%a=MP&1+^Qsoe&@6^62zvE}9%BJ8F|Zj{}P z2zze!aO)SxPNdC@I`-#GzjZdH{ONy@YvQ*c$}#D-xOM6B!WdxL9Jz_<(T-UjP(l8$ zQn-OZrgM}Hb~l811s#KH&S2O|MBnWc{1B-|X$N?FVc>EFxi@!mFVh^*PX7%g|6Q7S zy35(0w&yXPs~=t2LtM~-kD`Y1^k$8S;7D+Qr0BQ^CFlt`Kc4j(aWlSWCdkmVra z&g^|xlZN3Agw=$!-=0Cy>3p(@@&3}(S3E}*dy+!d5ekQKP=}Ke4N7CMMZAQ4=oF%L zqIyr8PBCt!i6;_}7=~eRH`|&|*>NCj3R=oY#B=U*wfTM2sj%KSmx|Mf*VW0yB_)h! zps4AS^`0?t((S8n?U66rrq$T^gYS+BS0uYyqC6Gf5tTC78LFuX0-Au2)VIz0a^Ie& zQ$M_KmDjh^Q=7M*^=Bkx!UwC2gjj@h!ryU^t$2tWVtZg1?nD<70tB1_&!DKi_u2oy zG4p;U`d)$j&v=F7MCO8E&Tcnhh&6>7ff<(f(*I(4%P(W{y|;O~fF~zPG zVJwM!)&#`>Ji<6E$J|hyYk90jLJ<+u@;Cyla3U0x4YrfQ^BWg6fiR&>0m7L|5sJai%l5HabtqB>%;~l%qyl#3WVdYA z9s9H*hs@yVCzikiAdl0D zJcX6%onZe^8ojh4W;k*pO%G##qexiNw1_V=nTMVdl$^S$Gpm#D5oIGWAC_$LRo43@ryFZn}N}~MyId0EUm^%5%Q>3a!w-V zk-cAU1De|Ji#HmNSwcqF6>Q5Zi>7d^q85QlIS z%7w{Z=K;Z70I{NK&@hYbAtL&Vy-NVUnJaM7VMlVjUsI!@xBwutMI681IU#-=aG2;u zVE_b+VGz8tDjI)BM;(Bfb+6#__$rk4!Hu0pfIf~-o&{{!^d2N9K11x+I*eN_k;Cy< zqNHpG!*w;v?F^XhVm%z!N?EIuDQm+rFR6+$lXR1w=U24D5&kJ47L}4b6hCluXIQVC z89R>!kyGWBO(q;U7dB-PHz``=hlj(OS0#}h7>Ha5Nd3sXOH}A_nCanGW~eoupj!iQ z75zMBYr+cs`NZI5JxGf5h&*&#ttzt85Z3x1C|JRuyap{J+Q7gI&sEG$8Nv{2)yt8! z_@Vl=S_QWF!8F-w7n|7_9ol`l?xM(+)gJhGA~pfnRs6Ve9E#j6xnufIWqfXtD zL5J!vZ=0(6Ao1D65zK)4*Y4Nunv1-2fRNC{vi1D9gIvRwiF!KsvdufyzqIB?nNf9D9 zqz-=GHpt6Bs!@R{$#zS`pk%BlxvCdClXWput#G#@H$ris6SEVT0(Hy`6l)i86UZh^ zH^(~Xem0j>Yso}?Vn{aexhZ&og9;vKPHKw_n^mJ}u73~v$T6NxyG}=b&X^3LajS>^ z=J2Z!V_};lMMO~ST#zD^EKx8|uUq%gT#yZAQJpMO?puvSSEHrh)WLnaG4K@s+kw@N z+B$W@byKaKG<(DSWKG(rkHFSB|1$`OG=?+1%x>J4NTTS^%Oi<{F0C<(0npdaKZ?Kh~kH$v5mY$r>R{w zl3vmDVH{t@#YvTX_lUA#xL2kC|6XB`wWBORdjW1&{CMS z_mr}z7r3M+@uOjH%C>&NYxrCKDUMGt*XsC0^<<4(#iFv++T~<)o6{hiBl|&oi}|sm zsb2f1TQu=pxj`8BR3U`|uPAb(p1+yAPEE4zY*uyE_L&H*2-FWCm~XWn55}z9PZ=G_ zcH3{yI&8lc?{n_1;Tni~>~J_=adnOhAJ@OATyy4T?a^)mmFW3wz?&Plj8k#B3!}s+ zs%oXa{2p}XW;~Bx@J=YbBO%x$9pCRBad12QSl#o)r%~D#YGr%zVtK>O)t(V^!*XVA zVZg6olgwWIMPS9Ua(=?X%KXIs>|o;igX!d9WBpZ|#<|?X$!3JTeplD`iq^Rc7uVmm zOZ|s8Az!X41;hoSpB<-{@!5+@rkBaitDG+$CaZm_J88@RAQbG<;3|wQc!MTo5?XHz zqHwo+$Hig9;GvLxW|)rgKH~B3*nT0%;$#2p)S)Ah44vH{&WAWs)eZ2>8OiXFzd1tt zv#C&Srfpli8#(J6m?8BCoYD~%sPd9mGg?JK>_Wzamf=Jsbx&*9l-@*wW7u5sYogl& zg9)DCs(EAr`aIH*!BIRsfJ%5g6@-~eQ{s&#Sv7@x_CG?SOziEc>s+9NyyFJ?M-jU- zdmXGk88o5j3B#6h(JGoY^-5`((GfH%)`_uIsrEWClt5XLlTaR7_6BJ@5e6!&y(??fAUlb7;aXI?Q$acDU_=BYGc?I-4?FuP%LxTd5!w zj;}v=tc6>lgGC?a(?0UtxXDo~B}P6IGoQRgJiQ?55+D8Hn&U6DTwlT`><~a}yHG=0 zEYEihn97kjbF}C!C#q!kE&ap}-GkEYO@< zs&SlIAv$U^Uf6HNQ0v}(yulGWRw%d=9Ejz+>|4+zpW+Kn4;7f>JGc4LRZ2eAaehIf z{7~LFMCahE@S|58Na&6fOK3g^>p0LauFhSS1}+@VlQwc>^K_Aql_B>>$S7|Q`H09W%lfdh2HXa_O0=<>Bpl<75Pp_2 zYd!J}iQPgCq=dX!9bc2|CyPOlzXs+rCcRhj8t7XB5w(KO=7=nGx_6D2l)=eBvupZL z^AAdMPGVAn7$O7AVXif|OCzI!9% zhp`NNVw%Q$V+}6H>Js`pxewb|>Y!YT>S=bFWVR$YjmUL?6 zLZyg+FC4ROogP;m%*;Zt`@HP!{eRcR#Cqnv@HM=5iQn!x(^9qEYp1yy%%@)*ZgtzQ z(g9mDdrciAQ2Pgs^OT~=8HJC33-E<`^E*H|s5z+92o#9O3KEItO25kyXm>lJKGHt+ z&QChwF$E@_Rfw}r7-)A@ev5Ko`Psv(z>pC??8?v1l+^dH?Y}}HGWNFHLp6}i#Bq5B zXlMhnCl%e4LlZh5aN#TWFYRiJoE!TrM?Q2wV1#kc`gJao(C<~HHO+HRW^*tOM?y9K z-5pg}n9uB==A*E|pp!G@L`cw{G%B5>dU@DhzFvz8Keo5J3}Y_6PUtKoTqG*qMcuJy z7?kjQ|LmY#x7r2hG-DaO%vCI>IF?s~n3 zr}>u244=skuG3-lE3vJRVNBazX82mJ!r=Tg2s3}8ID>V7wG4Mz5%BA0p>*ZjDQe@k zX4>sK0y9-wcw1`*B15Zn{%LAj&%b0FZQixktg7_MRnrP($vP39C)rn76UemG)@@w1 zvBcll2DTCh?U{LgAj*uZAYhG+WglWD+ZfM>@O&8LE0z*d5zhDKUy9Wv(Om)Ao+fv4 z)(LyRIT{X|OkRiWze=J8-f=?_SCMV`6khrwq34e42foq>ru0hgx+6MMyn-?@H?i#_ zk=!Lq42YoiB2uMKcI6DHCwc}>H&?dLyLXxPGFjoFK4n}oo&nUZ64Zu{+@Vl9YYy#Z zSW-P!l>RzRlVQUT6?~i-*65qqv9YUP4Fj9t7Hlo#LN%=8$)6Z4?=;$KhsBEG8MD3A z$HRV^Yn1&=V30=Hp-tI6e*9n=cV|sAvx4kke1OKKX!`Jh+n8)ty(-4_TQR+&_N8AfA=RFSzJzos^M;H zrDRm|MvsbzntgQV(r%>O!@w;#0LslkSQDSAe!K4tI74b z-?&X9GP%yEKB`tfCo~^L`JoopNK9)4KhH}=c$4ys{osZv zHHnmaX~0=%uB`}2@fZ%I(%~|`g$(Tx*ZAf65P?Q@y~Gi_GtjJwg(I%{Gh-W5QVf*o zLF)^HQRN=N;NGIk?@$1@sVJAH0CkF@>}OouT2za(7%7C1$hsKmgMJk7Ksa_tO~ zz%P+>>?`cbcGTRU-b`y zA6FD3g~fV!s2`Bvscu!bLTz)Y<1MMnM`Kko%*BXhs0x*vh|mA-d&$jiEJq4%QGr5! zTez8Ni&>AMJiM50ENDIIXlSMNt)#ljEuD=eg5dwVs{SaAT0Pqkv zC&OKTsXibUJR(|;a%|A*fW$N0$@t+W9EmvmU1Jh@S-o6~Q2Dc0z1^pMc?+@ZlIG@G z=Hv>_peJ<#L~&Wi1lmNXFP)qjJFkVe-?zmf3%LWmMQWNRz85=ndkRKZxvs7F$xi5$M6`uLY_u^Em!EXdGf7#SkNGaQOGNw3LSQm&8kYDs_nHJ9`3VJ(>`s0OBeliUY zPf?7UX`GyA2a8pO+s>uC{zx>nB+4GMX1e_?@B=CSSBDqslq^`~b#H=}>f-W!&tdp{ z8(k|ok-BXOjg-y_aybL(V!@m1Re!u#LsR?K<88B)&R!6fmPXu0w1hf`yFVG{2cNLA z6#bJS5Zn`st*?x*lSC1;?^$T7QL9{r9&am65Tef9tKK66)bau!I<1I7U771y<()NK z%U3Ic8yO-q!X9vbQ12K@Ozuv{2^$v?c;BlPo`pg(K*2+(!de6noxr?F8v1LUtGa!@ zxhS!9+KS*{CuU}PRr;>%=qYRbgKyl*)vCQpoK-){38u>!n>CQ@e?jUbzO_ZY_@8|% z25apJtWQrMG)twtCvKcHiTYYqbGhfB;vC*U1+1~dUu$XfPLkrALS!9)T=m0kRPaE3MKy4c%Ipxex=4t@0DIYwy1fTqZGXhK-JHT1h!jG2zT%4KU6pU2MX`P z=_e;ucqK0vKuv{+1%|x=)|3=z=X~J4qpYt}sP(4I$52L|=)9Q$mK1jQ8as{3_KQOs(KY33 zlt(=(A%W=AUrd7f%1cf;JyEbYSpUR zNPoAt=7)I&K4M65Kp+~HKU~n~pIG)$R`vr?0cf`L?)naqORz1MT*3RH`q<1I z-=vMSvQnG(Gk$8G@ypUBe8Sl1YEEj7H67GGZ6okBYNZq)ifTVNFl-@0V#F>|q5w9I z<-N3Hp=lQA;{6^}j669T5W@B_SCLdoOmT%hfvQUFB|IQF8M9SaSe_t_0 z>1>xic5SvkUT_~(uFT2TRq)Qk8R~E>_tYSDoPQK56pwTx+EN?+iGFr#KU5mDF~ubl zcaz=H&?Xvek?gN+|7}b2CNhk8*dbd#ZKS4B;Ucr^)tlU|in=a`u_;UXcaL@kAT5$D z?HmR*Yg7VcDFH)>M@9h;X~M*ktB_VdF92qc_^73D+0Q`|S;bPKhnB-Q_{1X8B|^vF z{f2uT0SHb3wW`m}@=U>6#9n+(_*9R_-4_-HssD)boU|J*e6vf%<%UInW0q2{)+O?g zDc5n);m&=IF$EQ#V1@Xi2Y}}kiNgn7?oGq#t?1+q7veT`*Hm|XXmNu6`c;dWI}6V- z@q;t|wddO;8#xPqMuFR&GpE5W zmoktdCe&ATqob5iN*q(&-RgD41)6^e`Gi9GUAvV}Yc017xwip7X4>Vi{-6sZdLhsx zUO6b2E_}BsiO2oi9%K&p?|5E2K>_8O+h+NeiMzAOutmh!^s^^j_MOkw=Phz;K^x}2 z$p1j$9OE9(K^fk|%kkc}0@DG*{sT*k2-?p1AlyfK*eapcWbri${Ux_Y`Egq0Y)!q; z3=H~J{RE{yZNPT7bgx{xKmmwdd}fplR;`xL zHoMU{%!bnJ@H03TNRpf*afDMbY6t)ba0^6Q$Q=kQTWtT}aSkipkWdM*wD;Ewz@dU% zTdrdfHVX&Ba-v?RPg(v7$`1x(%YO{ql}~M6I*PVz&gGO3%bAzGB;o1q$~SeYTT30< z4<=Hwd0|xv0eFjKLnw(5wbrm1G+>cK$<2pX z6Pn_s6P*q(n{3QKl_U<@{!AvB5Ow0wVJlx8 zvw&B2YrzCcGWx#864J_2ii%b8X}VbJKD=#;Q#<>_OdN&2>RZDUla0;2^}VNgd=5}w z5T$HmdkF8_C%W*^_#Cb8PZbMnSr$#5T2~&iHaIFpO`JBvIX0i(7QCj}-)2(kWFx#D z-`?g#^XRZ*DPgF?+a+Q_TxClEvwR?2Dlj0Sr>Y2mSa8goFqC5#e})#dN_o;poUNfe z*Ee84&WWRG=`?M$5IcB<8BjHdGj^itO7q9&hF_{o>m&;z)p;ulVcM8pmpe|*9p4M* zJ9ab@65g9lYRWEZ!uN=bxElWV&vW*R5+0n4*Ww#n6!X=P1V%BrQF$h2{~Oly#D1x@ z)Cv~|a0k^%t*PnbXC8Vy1va(c!zONx-SobG`JaY7?Gm<-Am@E&X+ay=~z?ZW3dPvAu@^nmr6!d<-wWQa&bg0hMIqqqOb%0(&+!jw(2H-Bx2@- z?{}*V&dZPZ;9qd#ukQM`QtT4p>Xxh@ zvvEvX#+Ro#Rmtq3<(R5biDuOL_{lcGYp!E`mg!E{yayucfj_D7ULy$pAxqg{yYVeN zIXbo^(yHHvBPB8Vm7M_&j{q_m)@ed8hkivxIY|RT#ZXWkX@a4d<2;I zwjSTUSdc1Zv}{(A(}pD6C1=u*YSA&N+%FZHoEgNZ(SV)rM4#Qrcj+=IFjGuBY|7yY zPLBY2=}W+*@WTq~G9C7RA-Q$o3Hh43V0M+i+o46fZ4?Wru;cDpiUvB1Wn%Q>O5GV> z`Q{}s_fqioYI20ERm)}1qSTeifMs?QWs)~W$PS+pC+(PuRgcF7f5?_87Y_)LON4B_ zf~w*v8b10|nmG95H3%X*{4@;}On~;05KOtiJ5h<=-qy}+Rle5CYkNcD+w$(KepypD zzE0ntXsWR!a*A{Eu<=QQ!*-P6P2ezNFbFCGv0>%S8?t%>iFWfu)ql)27P*KitFyob zb;OC%CsyT)Pb&?5!Gswr$c9t=nMzTe|Ctks$oiSZy0S#{D^3>V)LVl3gOLJ-P$fa1 zstB;RkB8Pp z0#o)A68>dpxLc@M-HVNs>rOjRetedn^OzLCx?a0}&*H~GEldBy>SzloFCVfAO z(F!~y@+^8j3@lm~Bl1)}Q_z0G$Io+rxPOEOzdr0l%@)!g8q}B6qtf}2_qyky_Gcpf zeg;OgcgarD(fFf+3P7E=l@y(J(j;%AmCS*hzR6x$Z|y zfmSwuHx|_`AR`szdsP8rvA>I0jxF4YeOwl0ESm4&533${8O zQPiypJ#U4(BC~&IE@~};^Mcx=3U#a2^nZGACjwXViwf~aQJCCm zvitA&5Cl%iNu%`TZyxw#_JBL>8Q2#nJGdZbA7GJIj;eO}f(ehcm5~iEh96+yNoMPE z4M>FnltMs7fL9sIT$DJ!C51UA8z~o$6n4v5^cjf>A_%#V>X*9Xe3M$L7{?K?bi(jz zQTo~_5s>}D$4o$&;}j#%9CLwF^i?ZaTX#Rn00I+Vl_p%bClB%^J+T;z@m!vT zFDOSKL&4C`-Lx(Px4cccz5eC}*60@%Zbajr$JGmAH)@_~O8s^Nu7t`v4v}F!cAly? z_LRa~OZL&K>Lnccx^v4KF9;4ZX$u*be@Ya-oM#l%>lhjI(b>%8H%@Kl`>Hti^uXsW z(;E=;>zX?ks~10ZlHTm|JlJrztn1_ET;E|kQvUtp@O;WJeiHvNZRsRJ)lbV>z#CJK zFvO$5&Z4ZB1x!c;UmeShMq8Fym%*4oHj>O_vb5imv*EUYi1u`L1Arm|Po}>}1Lda3 zHy`a?%iPpqtXRz?$RIuEZd~lk?9JfNB8Lnyu)NWS=;2(RKi7@=sj#Mz{@qhHKl;o= znvu$0mxK?Alz;a=d;e@e(QESNQxPA#&f@Jl>(p{V{{hXDc`|Q5eu?1s4zV+x+8iVs z5@(bX7l~?D!ZROU+dHC_^?k8;-u7GOag3M<9Z;6&p|;KnOe^M0rJP4Nq-CYF!7<4cm;vq0t|-&!K`d0_LP6G}Xg9i4WoKcGyJD$tYzfM|EH_`^kS>xcOauxth$hhTS@4_I z6*esD9?EFlA5zPD)??99ZpJ!t_K%RF{OVNbBtZuFFi1LflK_{v*s;>wW6=u3T*fU| zD55qKJeGK%Pu6gR@||OLbp5FBSUrB)+N1SBB_f@&`bK&qa4?#$oPSw-Ggw!2d*H2#h+B z>h9_I`|5c8=gxL}4%g4v3|$u$l`W2}PV<5`9ZS8R$jh%Ycy3rfF{c$}4`Y;zY;nx7 zXutq41Pa3{q{$xRv{I!mj-%l!w{6V&%e5z%S!=8Mg}10F5A!96oh8PXe$>zgRagm8 zFvl2uGx_X;A(b@QyhK=d@S0U|Hak{cQa7}}z*kQ`BZw~xuThgn5h*}!4dzD&XAKA0 z9;4C!#zBM((m9LQ4f8*e8N0)uAajh>4nIRuJPiWeyZuO}3#(p!lE`8y*XxnZqzX7& zW+c^7$r8NNTB=vpH&Cxm51AT{?BHE97AU>OhdV4$52fmmeC`10~O*h2PYb?SB&%kXfmQdkC#A^oG1SxWKB^ftoGt}?w}JCzv@EQ*{nJGFw!(q>d2 zBT=j@U29VI`(*%7V}VT?y+?Y`-BXq@bR?zqrPO7D*?XVP6S?jM`k?s&Fdf~O?*_|?u&XAnMJ*kNh z6&Jqz@?NtMwb9~KXGE%Da!1+v^=irgg^of@8-?ckD(`%&zgD^<4?S-_G74#*JFqNp zcnQjqNxcwwUW9;)p&;%2Y@ZMgP!xj`%0Lk53_$)BN0LY&{@O7RPRWC(Km<|YGN1wJ zJK777ZL~BG8I)D;2_KXOip@#yACG~t%iU-_v!JOAp^=rgP9`G3MnxZx(QqNd2#ctO z48yAlS@NSqf$me5y55crZ%g^Xt^D{#B=m18)8zFWx~YO$tsY$#S2 z9Fmn0hn1xtMJKF_Pj!l_XJO56k>jfJtZkXeT5cv-whwN%Vs^FO^!EJy_xl@C1z$@J z@=0^_%hTnTnZfNzurx{2nmR=@mf!!0!gqq7^43$~osZTB=a}S2z&oAkYo7mb3Ojtv z{f}MFMtHrEHHLR_|6CG&8b45GAjM?sNggJ`3h8gw1%|~}UJXXZCWJ<_?@?+(?TWOL zK=OQyk;9dW2<#y^AAmT%oD0qYpnvK(3{1nAz`~`_d!nion;j*ssH*H~0%;jwD4ttG z!>+=)_nuF*m?-#ID31R|kB zx}u+!p~L}~`_Wdp#5%P|p)APeNTvtmt*+86(_7(Lo>Wu!8V&g6mgp;BHdsn)F~D7N zZW7R||8D9Vy?i)vuX`Egu|MTiPGck|ou-Dru|S*LboP9@Ye~MIwclKdpta>Y|K5-J zHL5EDH#nS9EP3`-Vyt;<7tDr3aR}8X{7Ss2?pJ(xM1np~1X>P|Ouk4i3=#lTgl`H1 zXUZ9K3Kt*;cx>*SlX8!Y$u=*FPNijo;$tZTsX-V~1u|hENHU1e$122C+a*pS5~#|h z@&^r})t(I5&sVlM2>A=q?2M6Ci z(>-^?UVLhUKt=Ma$|D6|@(cS(Fb)XWRP(dxvISs-G!v?XlM@`^4tP>wUE|4nGDySS zX)HQGTzJ5UGK(-wahB}<1d&QS2X}k6zt&ZuogtFpH0XVSxuc`ZkYY>{O=0uG)GxwP zQz|AXLT~gOFsoH>p=&j@Sd(QG!bb8eORnCO>mydI#Q43Df%p4ya|4XK3>^tx+Fzqh zfM{Kg)S=>OZleIh^}L@-XS{~nLOg@t^o)P{7|W^XFJ(RZMpNJ zRL$Jq5v`L|laV3$7i#*3O6xx_cpa*^uUG*K#`lYRp5MPYzW&yj@%P+|jxS1=Zig@+ z;r`Dote;3B0zkwf^ME7eTm2H3GY9tv6i0)ZJVq5CBf8IJwg5PATF-sC%$b|t7vw@wNk zVwevbdRH!doP|O#bZKIUWVS0t1d&G{`48%(;Ph2f1A{RUeZpcP>;2Z!YhY@VJ&5#CdBr;r)o-gcx-<0eX zV&7BJNid2L7=x58QDEZRy;igXNfgc%79o)dG?bEt`8lDns)|hZmG+lNw`Ad=5C}$? zx;zsL4Uv`PK_QDRjd>`XF@=I5Ajc2rj0JkPa2ZXJHL<V$u`?F_r^fKM+Ll2dBkrmuQUxB4ZeH4vwL`0 zInriM4AHLmrNyYhjR~;du$uCb=fxhgQ%tm#WHPd9!5Q%mlQu6EV8OSxwBeyC$2=sl zlqU^C_#-Cq265pSh>y@Tup1D;gEd&JgKQ`M>>>ubEsBFL^l0-0B^S;P#00nuiVYaoX zFbNSQK9IW0+o*urhoT+i%>Cihho!$WuF(Dccl|h{cMlKOJv(k+%^o|-|KF%smVsoRkO+F9MnsdbGH*otG})5`DX~OLDFw&DsWF!0fVeUNU!>NAL(<5Mlzb{( zWfyGxWH(zlWEf+&Le@A5QbgZpwaW9EpKUvnY>rZFuQPO z-O$NhbRQ6ypey@B-uct#;Z4Wihm$Gyk?s4er%qj8d+%4?JY)$aJ?DPxw10Sb_qO+) z%$uB~VYx#HP$^GtJg-hG+(#>Ub-w(wMZ8pKnv`J_{aLs|Rl?pS1VtD(90F&9VgV08 z{cxDQ`8<{X(K4W%uYU^O%mn+dp)rZz_S{G*`cV{i<8w40!Ar&x4lJZwAz;_0GU*SJ zfCf^7>{IwD1kTo=n=D!gK%Clod}b?*h($z34v=m9HfzAevclqZ(5NoOz_xT*QT|~6 z^w(WD)fC>3I>z_$OFxL!0xrZ|9JMqL&$w;QB%Hq42xz~}{rHIKZvHD~N46k0#VcR& z>PQFra6NM;l(h2xfb8g@E-ap-c{{4IK?d_d@cwFVXhkx59Un^}W|Cg`k^QVhx z#C>Y{C)Wz*(jPayrWKmZ5?P-E%K z2#@Cns5k2oiN}f(b@WEr0c93h)Y&>=ebmZ3_a_m7hnX2(LPp12b$yN8p zW7K-b|M^tYH3{{vbv*d=sa=27<6+dys_SduhPSME3S3Q&s)_Do+{qpmN(7je>BRm= z#77N{{HR&t%Fe38c;{FJ(@$xd?I|+4Q`lFH?6N6wOCL&8)5{7IwtF1Q zOaqqR)R!=yi;AzCJ$$v)u+ifKP;M^T#A^fw#voQ7Ba#~H06RoZv|^SWVU)(`Mrbnc1f~||g{H}*N>2Vk zis6SW8q96#P;CZMOBykbWE6scPxXyx zQe7@OxeDxl?5Md$iBB;kslNP#9zMduroI7@(R~1+CiYZZmoA+wrP0d*TSvO zR()zT?Z^##oayNI1lMxmySslULT`QDPwpRXR1)&pdFAVLOnW?^e-c{zpBMfAE7>*e zo5#mTiTl6f{@&H5Byqh)V#?r?_`#YZwBx<#L+u#L0VzTJ&u}3Fzl9PoW91Z$8lU1A zd`cOJ2yvdYm(itVf(y=vb3Agw`ScpJ>^0ZSO=t{knW8TJ%$KtRTrw7qU^pz*eW4Fl{pYng`X3Fn5DiZlDHxG-gzWAPNG-*KnZSVe?RsYL zlxah6veX=Yh57FpRqJ6faA7V%Nll9)=K%XSnSw(#ot_GZ{r4J7g?vJ%C+P4O_*ga;e2uem;gfQet>01IuEXQJPgi+3b zDkIzJa&bimE?XaKYgtBFmS@^FkdVv)e}o)^>U2sQ zSf+kIu039}mt_Q!G#lfZY$lnBX*;sh;z9qqqzd|bS-AJ%xrg>?m_Dt2QRSO=f_PY= z6C&7H(es?y;hz<~|D#M-?w$|&Z8qY>-mt}T>HrbHv4NB9D}@JVbvN4c$c+A2`A!n$kSE>FR}B zWk{t_l7reDe937tuMufrJPbYy9jXPsLLFvx5>nhO3O13Dve5i^n%b#RFew-Yg|p45 zVxlKe6Bz~rqi8S`s%fyLOUkH(*;fpf+b#BFAcF!P+3}$hMNECRe4=Ioet!il7>J4B zfvaii`lK5nc1>JsMumkWkXjW1!F@s|NUa!qgmg|_N)am81`m%{Wi4mM)Hh?mm0NS@WPuw+A)Y*}@jUHo?(L?nQdAdrQCUG^FflSE-oMdrFTOk2>yv$|Y)ZlzhbgB@Z z93!HGLq~?ZoulpzRj+RYIh)H6+lfar+0NJUs-|S)W{#O7cr`();Fs%op<^sdty#0v zBvk?<#5`;m&YuCFviv2&(6NG(hJrw~c`%4E)sJKxY9uigfanmox#DTi2;dMF%|&Z( zA{RkG0)yceQQ%B;<9Wq#)KvnWv{c*l<@z0Qg!GgzsK|G^)z!9OHAFo|fn2EN`}VwS z;yeHFb?}*=;ba`C$3_`#OweJQ%S2FnL;&qXYE65%VT#YJzsP^0AeVIe#c(S6F>-nt z`z++EJ%IXG8rOeU3Lyf_Qqy%Efjb4)t-;&%533)9NG`S<>X)-;@lSr~PdxZ;dE}K= zw0?Nqsh}oR^Xs~;DNB1{viYzE$H++tIZ&^E=D1Naq4JP*yXt={{TY-9s&G5N+u}&0 zghPXUMVg^E3Se8H>Od90``T~_KNe_6p~N&devK4K_+@AS5vH7zEo?2!NCuHaQ$hZU zWyB|PsOoy-D!uh991#KVF0 zt3YBfM?17jhMqNFfG_6XQAzvtll+Z?6z>&@|ppZK*Wa6m?PEU)Wjyd4FqSKID$Z)*c5OE-LT;S zikvL-Y7ipCE#+v%I1QhzB{*eNL`2f&hc1AoGoxhR4^&Zx2LZFwV>VP>{Tp;MCdhn$ zQ|H4GIdv2=aoVXmp-FA3tq~)}akjyXi`=2E6tBw9vIe1yY*XsqB)vg7?^7E)S)Onq z7#adLcPNJf_66X>(+ooi`3v9Ksr_rtt}6{9X%}%fBw8=F7rwu|i1pL7w9}iSNIN$4 zeV638`Jb)x*Zm0Qtl0g>Sk)#N;_23?SF@!WequELuHX6?v1G_psvG|=>rnzvQs6X; z1p*DA!RAiU4eCe7g<-k?nP`Fy+!&i8lV2P7almWjr6Ba>WU|GWEJXQ?^qe&EAVwe} zw8=b76Eb1sAOVz310GwYh&bYBxz`ITEd%&$0kaG>e`T@q)stOyLxP0}!9PQ|sDMyn z94Iz085fIxR?Ylov#Kh(f9aJc4@wbj`Pt%X_{3!?U!sby3v%~;YVfTgeg&Br(>UL3 znVa9zh4ME`Wu!ngF8fTxJ933*74IK?s&(-XCoyH!$aF%)F{42G7Zk=Hq%#}B%K(`i ziv-9a>`f6|^Z-5(00klggnC$@M<|-O$A%0(!@EyXDgsJa=uUIk(s8y%1C<2?Fq4Bq z8m0?iq`1~n$LHq!B-%efY9A8Aeh~tu*TCY5E$t6GnPqIz3~J8+am{G#TFQ<9G5Xyg zaqZ;5r==_sz`|hfpDsa_vksWh}f{K4XChnagv%SNZYj2 z=Yz6wq1Nv?j7Q?8(h?}`%DgryULSF9k~RG^(vr^-ZJ7Nc58`4`B8=`In+qzf&1NVF;AHJIqA(SE^PAHj(R`pvC(*{nty_%tNoI;uK0>5EARQoMUC+Y!3SX zX}bwyDAW$M{Ps@xw7WK9&v~weTxUF`Vj9{lQu;XCi2XOBS!Y%3BKDhffe@DXucX5s zMgF3Yk+w^|vdIg_lbhmk2~g?m`&%Qh zpgDBVXo~pQCsP=B@i?TasKNsrH70|>C{-rKR!n`6X|#RekAaX0%%~6sIJ{31pb1&P zpZvjv(B%7&W1VoLky${_vuUXj9r>7Kf~{ka@!^Y{BzX(pqQ`66=$^HrXzFLL(lL%a zBJ#$Mk4x$OD%~PB3)O`s2h(jtKT7Pb4u%FUe{kO+#CCcq1AGk3Fb!}NxcRrLF7oN- z=48b;D{uNJ_m9U&bG##-?TEwu=l4BU0l7J|PJ!{8f8TV!dDNNMhrgc@Z*WVXgT{z` zTrgd~*1$<28tQvC{NU_}G>O1GGZfjEuxAv#2YQ~)p`mo+IH5Es~6=_a}C_11B#WU!xCIl9$8 zZct8ifNd*s!9jX{a%Qp$Te;-PK&4HkEX zYqwXtpN++`kp_X~cLajHGaLub-^}#ej@oxtF8u4xE|QYWE?mAnR-LBbM8Ac(%KY(2 zi->>02Icab7UiDa2u$!9pDJdG{{xFh6GKt>@xFr6QHpb1=4089Fm?g*DVm>;S4UWo zfr0o2NIKg9BRYeW9i14D83NRt0*IUMIo9jZAg)X65t5C4H?mC(&N))Dp#{iLM;r52 zI#=GsXkeG?RcJlA3z+nJ=uqTRTn#^NTh(D6jQ8bK=ElM0MQ-)z_tk!JN1@`a{aS6j zjhn3T6}7(7#gC>%n~{XmnTw8VmxU^4-Rp_(ymx-TFSD>*`%e^R2yXWcmHy){?bhbN zAGu3#iL|Gr7a`z_CMM~g2EgdupZC8$-KqRNet7-7 z-EPNso>zl`_j^`7oxQ!af&cCg9ukA@|JFa60=COXdH*AvU*9}D^vM2{3x130H{qI6 zQEr)RU{~ctd(ESzr>vyr`jaWAWPl`nKiQ|A1BTdOnB?XR48RhICMiMz!wTevLdao; z*kj@X!sJGyW%O+e#OlI(%Y;5?_ zNx$HH?NdTRIt7D4pIq)+cTPM;-%We=9N)}5 z+|zyhdZDo@*7N56*Fyp1?mDZ+@DX@0`|r)0Uk~pO=Lx;@&nA|Uu_Y))VgckXzb0JZ zb*acHi0>4N_&bUSVMRooBSP?z;uHubVkE^AWDpXWPlB+A0|6rdB1;fDh{92n&7wq} zh|GM=AhUz&}2f*-gByA=mw7O zDhE^N$kS)GcICnP_Kg+MvoFJZjJ58ap`-36ChRhAAj(8^Js2D zp~({xUjaALx4}pj$)An@nNXIOUCw2lqpLJNvq#Yk@iv$FHM|v7!p=&Vg$)j&0EX6? zp~SG$F9jf6|K8^J-@awf_`ax-W6t~i4-%h~YgnF;<33-_M))*Jni88G<{uIgANuB= z{NsJ^!-Lths~P!D;0MpY?XN;XQ9LX#7E>8sLRvEZM=-kqT5|#dBJBtC(f9EgXmY-L ze3|}tybTx_d7!B^_)2sC=JBO_c<7Ub07l@j1(hrFy}i&&dlTqj-&8VvfS4^DnhIOH z1QD%^nL14veAsMS3O=PD#Lv|!2@Mx78LU@Zl-E6ICnzE8_r#UtM~=u~4}xjs2A}i| zVgua(_&6|CO6+(%U_2L41|yyXK0c~k^q(l40idPH%9y_9z$9&Kx5v~67DsMniHZ=Y z$@6n?(4e&AE75QOZUybnJ%HsU}EPU)6_A-m${v z{8Q74Q`ajoM#T@96nwCJdyEnNzCb!Xi-`vfdS|=^N}G$fEIt?`+nI{?E-_Eu?prbt z30132m}<4$nf`3J)%Y?5Ffu;pnjYDZc=mph;H_1yX z;*kTj*@PbceR}aY&z*PsKQftf9+O_UUI~3o9s+>|0g`F7xPmg0nkA`@T;wS2bJ*NKlW-1w*S(ORnw_FPot0YByhr_MK z9!CrvV9-@ZwLD;X%YwOYV80KK$G^SP98^J~jLr7?BcxOc7zPWg)}jf>I2bwPx3;&3 z&i$e(cVALUNZnFjj3u(%@JmX;b*5IzBKC@qlhG>O%}=CmmhmcQ9+MQo8w^S#gpc!9 zh?eVN19-n2V=2$D$CZfEOx zpsCO#;NuwjX`HV9)ty%LltFu<(13CTLL8d&gjO_5p~%jw+-SjnFS+LV#DFwTB;=U> zr|IG;!_!v|)HY-63n< zasKaBF+8n!*lLY?0}KUqhslZZYbPb~!qb(n_ZIBFYH^GElzlSUtXj%N-!|Mh%X9}E zx2|;O-gngtn7*WSG5xpglzVCUx{FOQo{^d!h1akI{G(~Z`_kFSzno31w1b=vHt@ww zVMt!+WKY%~MLnl(ZFrpFsFXc5<#k0Ik^c6uOrA5c<6d|vCQLq%7PshXyAZE* zFAi&6K-*p=96hR;^Q4HKXI4+?r`+zRb|blpokE;I`&1E?bmBXdjfQxE^PP3&9AIMrGQ)@=DRJq^-HOmML(X z1o7}w`VYGDP{g4ZB!)M4~qcmg(t8~k|MTflQ(7tvE*S#1eB+Nofu*%oK6Mi-r`&>rqV*N(IP zti}$rqKVF^F)y1eSff|Vgs0w%rP-_(g`Mwi{c)bfUEmmd+(loV{W`nCuBMczB%sn= z@2uw2E8$!@#~+W?r-Ps3WBbn8Cgll#w9(+&L=||ri>0Dj z$h6%Im z%;6klvYe{jhH`4*80*X!0wIDFmCz52hwQGxz0|=?-K#iPZ^*t6kl8{K(g}SrqI?{M8@R<6n6>}Z4tykCdA@(<`Xs4L zZQPj@_&V&Sn$|XWyXZ~WDSnYfaPmc16_!8Wd_r=}>{yQFVIy2H#QqGsiLi;Zg@`K# z*Rvy6x=d@(-Q;HmmMm3&BcTXR3J0f2A%hgXJS`QBFgCRI37~Mzu+%;zRhP;78)5=c zX`SA1z8^`A5|C1CFt8@+n-A3;w^WV2QlWZu!?M^2AfXIDl#MA?XnFSgtUMdbs&m9U z?$1sCnZlJODbdim$lH&tnX)e7Qhb6rxM30soDwgiL|V?yq&ghiX&MMxhwMgi!>a41 zs#tv^v%iYHK&F;?_X+{Qv9h(TKUe%(E0CgodOme*MJ|Y!d2SS)bn3?Wm5@K z?|N;pRZtvq*6Q=E4Wtf!WZhAFs55VM{M35Y0mYejeop4KL>W3yQwZzOdntgirC=FF zFADB1%NFpw@UK9*^thN|!9tU&Ai0g)JZ^8gEhY6-v2&Cl9ap{mwAU;B%${eWH+4dF z>lgs|lMF*E59Mc?!|NX;YC0Gdkyqh*iTtuUL~wd$MX9+msLBg&%pD;VzjioSL$6q| zC88vYBZ^#OmqA(%PcylO#7L!eJ%>z@V_l&7ox@5o$CTUgD=pJMBoK!j|FZH)`ynhy zD<)z7@^DX0iPv$I+7L56hlGMR#$OfR74ArM=F5?G8@!X?(HRymYHYdp5*ku~W#spi zL0CIFaatpbG(6aSB$Ku+Zw)`Q$*hKz@v_q!TO*gQjw6wa9~h5cs$5LGX6%`y+l<4P zHsJYLe^9Bw{_L~(t>ucjX_nK>Fj$S;?>|v+Cb<3Lt`+|35vOo*u4(g#Sozm0jklLD z=qPj=TG80i=jY7&vMQ{4Bw-{+K5dus>AWN5fw^{TKx)lnnX9058`UXBMrOl*{7X;O zQK*G(#kqg}g>y!XEVBbH`l!swS)N2kXN_>}oeD03{A$S2bTz*ub_Q>elj&{CmG0kx zF|GPebZWO;mz=VO9@m$Iku`gNp`)!tTT}V;+a~cQhNf6?Ui-vNB)gFHw=`Bwyh1T$ zzh3YDb>zI)uwt2r-}&BY)_x&oMGS8Cc)x<#SH*9V!aE#fWThNSquVYtSH-hM%YB#me^N zPxYV69`n4edI6Ff)nE=jl+&mAuwE5|(ltij#3WHtX{Kb%H|g;OZJb3HDW0oKcUG@G zX`9>SF+~P7e(Z5@Sktc(F|cwCW8w8&(Xg^?F#R-LF-c}xPl_R>Q@+=_PBs3jNL}Yi zKU)IF8qK=YRVX+HB3TG444tbY*^{I&7gb8lEZ%pmOn`&5kCwI+$bQ6>iht_I+DM?9 zMUACjP3Czz<^}I6(&=~wMC_Qzk6q4 zS0?QT-JF&<4oflfE32x#NMh}d$jGRD`-mGM^{Q@68~9RI5}UgufEbFMR_#79&3<}* z^U~+fSfCMSNASmgIxwhVI(2Sb=txLD+ZxJ`FF%4lsM1f8!?y*49NlJsfm`vS%HsSu z@rf&;%d^xerpi@(Iiw5w9eu_Tai*3`&SqKIXCniHPvd&18k~i{&O&Sfw%TsCT__i_ z>ay1S2{fD~sIX2>*10K3*Xqfa3Y2&hr<5aYQ(5W%;1uczZZF+6z^|-4HeF&aUqM|> zB&vk}OMM9MUWUDrNCe50OP3B0vuUFejRqCxbsz0_Mhe7AjN!qsZe!G4HrnXI-N$|C2 z*0}!7X6&|=?0AOR$Z&2>orxPLwGb>44#WfzvxY=I0;Vux^ckNYLie-@0@79%M)AM~}f6~utTcm?T0 z^{Yj(u78D?636y+NEvr1`|x<@W3WqY+clxFdeR01%p+qYth$wm=Zv`saR)79R;&|6 z<;b=dvC>DDngL*_&7eg`?#k@< zJ@>uU#3p;3B*)!E+7!DcVUSSlh`BlLj-Lb9I1!zY9sPC_Yh$?@@zZT?T1K;CCL#B^ z^v?zUMqvEt!2vi%E{p|(Bj>Tj0p3sv8GRsb51CyS7sw07&24@6fcER(7&+y^X=!Pm~(M4 zL#E?WHF=!zVnzvKcq);m?#ZIh8q^XhpEc(5IxJ}2)Vav#-;^+-aTYCZ75aak{fMjA zk>n&Bm-&6wu?j zna;9LFr+IRoi1OD-%P6y_ziR!Zl0B2z9=UCwMk&%CwAH)4Bvu%MLr zp*vSAhA3%P@X4nNMzOx-9Y;fNarN%Voo1VpIDtPWLqbd3x*T*Ql!;d7Eu|$#5pA^k zF-8hw-zHL1Ra(lFk9uZXm6I!?8bw4<1tqhT`v#jpYD(#4todY4WJ?nXT(!*i_MF6%l& zJfW`e;XE$p3XLUS__;k;XBGO+S!|$x~v}VH{IIL0(eTb#2Y2qQn>`L zk_5XQ1&@*ZWtB*hc0NTiK!hzD84EOug$r1Y6MC!`b4(UBxT#@$jT027gdN4kE_EHB>tCm*(mqkzJ@k-dwKLe!X5jE?PP8ADMsj^HDJO0u!~I~4LlpVk zpEP4r#hIm-@|>F_zN~a==5}0e#G_n~ZB}OZ9rx7gt2(l5Z+%}Kx?JfsV^XR&{I9K( z>PkxlzP=vLxiTVNSS_@U ze$nDL_*?=gUs6$019y7lw5meRNKfk##pyaoPvvu!{wAZ;i%#KZ=05)pT=HzpWAb$< zYy$B~zAY!;5Uc7)M^Y1s2tEsc@^ayPKFyvpW_xBoXa_f`{VPI|n4g;kQAHs%{_mMr z5&zf)qNNLk#fq5gL^e1goih+W`H{l*VCoSd7OPTBU#7Y_E#r{#jxkD@*j&XRc!CkyEMfg6aqPAY}qf?coR#c$Yq#JA9nZxz9fxD%` z>m=%ed2>;DbvaS+SZSY#ZnkM=g&&p5`c5DpCP-C>4BEgGpRA_-fi3=CNKI8Oo`p)) z5DtPI;3$>gOG-)#(r|a0pXiX|3NsF3!jSHEeM2fBAk<_6AnV;7u_BmJEIqyvBQwfE z27MngQcsopUM|el5=pEF2%(AIhff<>I&fy@e#`}b*=?L;cQ*PpO1bH(e3qHsFKH`f z&=T~FYHo}vt$80iX6-Z}s#A31nZB-Nfc`TV_j6r`b*9?J)huj`fUctw&myaDbE0i9 zc~OPna+XAL)B4~_?%?Od>U2_hw_)2$-e12}AYJ0<X$D6;X`1o^9(wZzVDJ&k z(pBQi;l|RF(C$q)z{2I&Fj9A*$)Mj2-Y0EMflZ;Vi4BqpwP>O+{}LB&b4&@oG<^J2 zR*fK9Bo>C3lB7%+bwik>hK3@r8Kvet1hc_wEbUIUo47Rdp?_elj;| zX|s(}oU;vDB_d@M7z$eDClQ`*q|7~jjkowoK3xCQ-MI3%VUbK6&bPwh*IWiK0-tD< z)v|rFUShZW*lp}`Yx_D~s+klsd%v7E&-)*Q)6OO=_EV`hdCSF1bW=gTApx_RO9R$Rk4=mESypFu=ZPpSFwBXysq~Vi~)~ zyuu-|sb$Y>k6k2wRx*= z@6{|dKN3!Tx1!Q4Hew)EVQ1a%=>7A?5dl%;Yke+Kl_?w_3?pR`i#=u_z^n`b4663? zEe-d1jk_`RxoOfs1ez85J`D;V#49f9LdI}KaORR3864%Pg&B^Bv|1p*x0o1D8$ckd zI4o&y1LiCFJuMqRs()vl!AEEA8Jj;ktT(mq?y>#;W!=QQr0JV_PbEz-5`_ zQ#M4@M%|fWs<^aq_6^)cI{SwXrLSTJ*~W$jtgWBJZA+|};!0W`(_#yF>L5_Z09EJK z+#8+>qxDtmIj21D=Q``D+i6rKb>ucKB}P5=C0aMKa{0^!n}22fSpd6e^Ly=MmMAxy zkuZ6t$W&`x;$zCbZ1a!!BLsbxOn`E5NQ5~KI0^tCf&d5sw3+A|J_07&&;$t!wgLJ~ zERZ4slKwiN7q>!24<@NdFG>*$R5$=|zwMf~z@#y^SQIyfg8_ITze2&W#!#uY!lR>% zKB(Y@Xtu20^&hIho%CW;NX42_X1OyWS*6PFf?s-P$iO>vMRt}80PdSSO|E9Ti|!nN?#bAli2 zK4~@p7SCL90Rh|CB8y1cmxp(n)LFWI0tOVz-sam@8mdlW+uWZ6Uq17Wf60A+hjVR< z(b!{oQ+|P_*ty5#PD=XligdU+vd?1tR#We5?+-$VNUU3b{zt0u6#t&QsFe9cKhyISemN%%se;bS)rFseh>kX5{K;M6IJ#7Z7|+W#D7o z1&L?1C$DvrkceDjkIUQk->Y|@k&MbU+FMr{HLU^&ax7vRn&dQ5N?`PDHtgPPw+8h;v-u~U>Ni)WcZ}KKZWJ+l%h!g4@+kq*VOyJ|1ky(7%<1iX!~>{`|i8KYN_>c5oLDoqf#g-m#0<(NTDt}w{6d0L;!92{6;H)?*BzJHKX7m9QW{@DI`oLSTX2KSS2JDW$*;8k%Ejk&>j zs{A5PZC&~BnfCbY@%8XU74lKBBqQViPt+l$Dn6PD^%;Us@`(tQO?l{qlShSOA!1Vz z&W<2V3=SLpJWFzm=1`oULZlwN1C(Y-(Y3nl|=&nvuYZvsYU$m)RfOWo1ugjTBxNdU7!I zb|ek`Ckm%2zgEmfBCs}v8xrvOf1)Kcds@b2$wHhzjGoPSg;F>kDhMdXO;Y zFS>$t^P<1PzuNZD+MWFDdlaW?@=ajuTOt2YnaG55WaDL!xmn~^PwLn?m8*$W-K3U^ z9izpJoJ;G@kG65~d@W=7zWt;v%N38Mv$Mj6+riMCyZbY_(3_?+EcSky%U}kdwCMvv zSnFQUrh+CKXTr-)NAOUrq{2>K)KLpDjY=itMC{7g@`6-}0btYz@f$(F1aX?;>&~BIyk?NL-bd9Yd_d*UG{#s_xwUE|% zY?LA=z*o(}ne3%0E`!^w$gvmgj~P?H>LL2p9Nfo?{N&;&*k00h&SsOqbl!$Da$3^y zB&FPUN9av!ikp`EMP`tlO{aA zjt$~1C0>eLpx)OJ;|*Fsh&hPVQMXd;t&8xI?-No`i$aME9_}i`DR2x(Y{=j;gqK*; zExZ*3WWEr&O6|Jnre^A5DPD>+gnjDIN`fWg3};gE(^~L!NT9QjI4_UTNJJz^%pSk$ zJv%Rx9c$Gq21kO=05*gww;V4MKj**{0;~*z(wSwg+MzSg;vc>tVy%!ewSR65Ec9R< z7`DX_su8pu=GrjN0JQ{++?2vkvj#ggITpsv7axu=624?Pq{}43ofxuk*>Lk{9C>}) z0d8_>Y4kh%qAsX)i0b6{Vl84e`S#0D_l#)aptRTri;J3*oC6w>-WMGu;O&4Dx95EU z1#P{ibyOWY_uua?NBM%IgPa0)e@bg8bj26s=*^onX-G;6Z{Oda-C$px|KG0OPhxA} z{=KsPzhf{+mr}Y^@C`~ke1w9q zJkcd2?1RWNm>sBu7~Tfl$7j}sC*$pf#lwBTtvJj;Zc8@(w=wkLY=Snl0MRh!utXcj zen%zNXlQ;oJDPYq+%Q%Ip_W!g{v4MWm?w{Mbfub2aL>?8?FADGW3v7y3IL+jc-80^ zC|o=88t9BO!0nGXoOTNUxf^;jD4B{=iAP?60H`v2B&Vh&Yd4+T67n%1kC07zI(QC% zMzH`=bxX$6h&l@KB&RK?%M;=wjjR3s7EED)hxB>d0;z-9qk{ z)Z(#jp?RxqS{vgl*QfWPbQg6q@BN9=-#(D;_hkrR75mmntdV(uHRk`{ea8O$al^jP zmz_4-zW06q{yQC%?OS_^nQFO@wj$K(!BLp5=lPwjd1BsE8ueL(PEqu>Q{)?1B+@~Y zQ=42g3YRDK(*^T$+vaGy)q2!wm<<4CijxQePO;-E44q3cz{|3!CLd5B<<7x@@0ABF zBLMtM+%$AS+3dU3A`1&y+8OZi804^+Ff($4k`tw4xs zzKxOZ{_+H&@K&6UmU*w^COSUs3eB7s=KM?_elHL}^was9@#d-j7XPiorVkfGXTtV0 zv%{L=u$iUQ(h5iKQFKU+w#oZ9-wm@L_kFD)9MXC>&t9T;#KDOZj!vzf}@IZDQmgops~#;Tb&KP*Ea6{O+n0~5w2 z^o<{kElE>n?xv%tN=oAQ0xsT!7_swkpV_(C#!qvZrx3}eFsN;-CZMK#s-U(?4NQ@3d|NbdQ4ES^aElQ_)Q zCOnW|oL-qS^Y_ETcQtM9QTg4*$OGjjt2qv8Zq5ZS7P#e?2uWlF&Rx!&Y4IEen_2 z6XdWvV;pM*3{@qE1-hX|)8Iasl6r3ad!7ZEL z#&tVT%iU<3TIh$CzbM(tn-+#FwY{SKi%`Qy-zjO$!d@BSDgD?y_HEF2{O5jLc5M%H zh~cT%_3tH_eA-hS5Gts1awoR6BOb~JgHc)?B;yEY5b?oT(QM78rdIYtXeA;w;Lc9~ zQh-$8(Em#`K2NlurtaT7ZcQ_N=Q{9UASWW2bCh;IhItH!R0L8r=OW4Sa0t^;l`=Mv zE)!$0k0|ofd!AXFjb1NR)|1>?3Esc! zSo+-NM@RaSFHq*X;~m{bZv`x^qtKdusa1PJe1yd~;U6#Qn-+&L{eH@fp;>aTqePHA zSd{e9ckb~v)pl!%AE{CXcYFg`G+vtO@C?E)A*9~!o&5dn9J@amQg77YG4Y1&0`~Ak zLF$A=eGXO2pa?AuQ zzYRY(KaVvn-PK4Yenn_O|i$r|+2BH6z&VP@ZdzJ$fD( z!n|Bd8Am0=ob&8nx$0zinGFk17^WYCle));hpV7V9t^vQ#F7N5S(TfIub${H-F|~F zKPF~PG(u^sgcmTFl_-|FlNUYtpnXcTZtgj4@cGO1`{V73zcMGxl>t-ObMT=?ZCC09=XZKSZo(V z=moY&&Ti*l=q04B;qLmrzD?UC_(AfsRDXi z4}=QcZytJv-uE1e4PVM?$cnLqh}rE3~ z3a)Di=S~p*Yywxdm5>k(5X4W-ho+jcZ^tLf@eeH|QGmwqk&#qWg^BKgn9-?d#Da=y z0%8JBch--JeI#ti7P0p^%#f2?FcOZSf|OA3PE1Z0R^p`jocDN|>qy%t zYLmGXzbgWEA`K(B?1Toz9f*+(#N;orICbRD_q~-Vm@LPeqAvD9UhDJ!M8O(B=j9`U>%#FQ)`c0N2U1u!jH zJV2~eVNI}Hj@*g>BJ#{!W{p%lSZ&DwPEs7p6r{w4i_=ximUVxyyku~y-+K;58Y3eZNueOT`vMD}XL z`x(-v;xpwi^1D&61&duqkm@Jm%`6b+i zph~!S{+|hsXKWEHAtkTcy4Y)4r<6?WBrDI6#!Eu7#R0w}9$VA@ZoLmndxG|je?D3^ zdqv%P^djX*t#9Vx=*#>2fvv4q*j1~4|L$&f&i-fa#STf%E5DzemX5_k|C1KDt;T-C9cqw@n6%qzF5&4z|8`kzxXt(PnA!@zG`h#hD_QFeK?j6 zw#gNsvL`oB?R4A>`VjtlthdW|$Fcr1CFz8%q}!R6iYwA!bK*eY{lyHg#)Fk3uY=fI zE_!S7h?X9^(>bDw~U~>xhLzVim+Nv6RRMfJ`dHD?U_1 z+c|&{F1&9~LPsZtQm_%n$ALx@567UDQB|CzdpbFK zJg<*bjwnE3%zKwj>YjUjFRTNSuMRaRqq@n}GAJTguH+N62>%lW4YHpjW@ES;7GCR+ zF6avnPYaR^W-=F#L3c5Bg>MR-M~hH?#xN?G*z$Ig;w-Y!IIb8Qh~pp2iDWd3NO}-| zxA{T0Z+b!1x5vSfx_{o)WLCO&zHof{a=h}g_5MCPl-KF8AI_~QMi~r&e1wmdq$a_1 z?5EsKNdgGPMpBUw9)MJTGx^j*GztS{Qv#V{OqmFx&M}6x;r%1{bguimb}erK&SoXW z_yBVJJRUS0_=$#6$je)F*`GrK=1y0ZM3$0dC50hif@FN7azNPc7R4#>uYJfqsu zE!<$RrKE{2gIk-6nxK`Ok;`LADtqc``PCYx4Id-N2y4u|7Kf*W4`8gVRN9Pl!lv%U z3R4im$_XAud$O*UK0Wl+_doN`i?-ZM>`&v{pJu+}``Z}T;Hrlw-*lhXN)<4KL6RqO zD@rX!OH6r9KxR*?5`QC1$N0q|v!RR&D0VS7`Y~{*c=T2^t>8pp~`nM zzG%kY5yVTVUzKNE^ryhjhT=EL#;ea0F_Ba8R)O&na{eT)q^)6@05<&8&pjJzs}XUy ze`|u&cXcmy6v{CX3HEP^9=K*KoyPa>koZ1z3-DVwHhVShzIgF8^m68p?r&`WZQ5JX z%gV(ID@7kG!Mgf1@-?7&P6gzRU)W&RQEO3N4CrtKh5VP+5rvgZTfPYM$F;W)P&hX36(J=|W~%UMRVWSo2v+O>FC1k4py zbs=~s@{jvKZL6u1qQ`vXG0DLCb<{47mIli>7hyOmm)5ypv@8w8HAcamrQjY3F zDJkrio2qnpWk$eg7bR+j@+o4^%&WoG=eCg2RiTnue^*`b=*yA@vXaa7=;==H^W~rw zJxUds`+L{yY;;B~gdhS}*I(RAGs5icTM;N=pFd1cLbbD6 zt}yinv6w5KO_jybQvTg~NY0T0Gd9fv{{uNmSxzT6d?N#z2%`un3Qx=(V8ceZrheje zaJKn;Jt8HnM)xDI=Axxl#<=H7|#a#lSjRrXREO$!|Q1+ zQz1Y3oYt_tM#5ydb!OHMe|hJwEjNbet`!ek+}Xut_t^GS%tA6k3G-CUmN$Y3tqCs& zoqr04+u{1+V(#D_1YuAJ_G^k6qb8v%&$i#B!Bqk~|0fE`WQVu*Y7y&hUK{*1&==aC zmi-pYWFAR_g(3$k-yU^xLru}?An5baif}#kTv~*!?Gusce6>BmF2YL=n9T;501F4c z4Sz7)D(y?YB%Dz9f+P5;7{^;@=^g*$-CxPJ<`?qwEv{mjkV%5UQ#riORgPgGTF@RJ z_868!#3upgpat$fAc(KEUw&D}%5j7U5qH=;X06aOsL}EIkoURH+_M{!-(l_|*j8J~ zwep9a)i|k0G}hw&W>`~0F7Ojeu1L&obo~@9Cr4aF*mk~bLiHSVJkDIWms+k+m^Yf+ zE|(nuhan)e0A|c4d3++Lo1ASWz`m9Gfd&OWlp+oM1?D_Ok~ro}#ej+!$tGf8GQ<}R zALJlpVxhyK5YqC}rTdjrKHy7=3k%Z&fQ+Vq0M?`4Anvl^VPC3)v5~|BS#VkPp7z}Mm3RLKe)Q40Z$AC{?8VgKivjN;rJX*!*BTHYprZdJ{#2!Y;Bd3^ zl%@t zi69N<f~w;-cX)mgR&Gwg9pY7ZN~8!B$~V74?4OvK-9Y5#zLIC|rR+yQR*N&qj!r zEqa4X8TfOkLuW*C{$w~}Hki;(pK2^apNl#qO1~au$g`2yHV`?fuTbplY)g)(_EOF} ziF$vOAk*Hfp5&#?-JU1=T$%B&-i!KgZ{5%Sxc&_LkrzbKaes7whaL9F-v457dTfo= zA#63tlc#Vs;2<^5n1~Y6fVYefE=0)2FmTKHz!$Fs0rvw&KvVnSY-E?9l80b?15j8V zoS7obXkqPLKR1v`>^+1wLe2DJhV;jQgzy{y>zE!ofjJk#D&|}a#DUF!<|NT)Rf-1a zmgvFolNCX?k?y>dpvOpoDQZqC{A@3t1bmAXaY{R)dR~?Q>Ddky(kq^2inZrKdL$p6 z`(5q1|igZ>8f%A!DM!&mZ#*XF~^;(@<80+!!QuwCcMkkTRw3;RCg z9%vO9OXWsY{li#Bjx5b^VFr3)=~=Aw1rT+4LI zpxdTu(XngrFFvTd{ZmwketUmg(Y(}nu(Pt?@a#a}$^q%zlPm`fCL?!#UQ_mXSPSqH zm24Dkt|?;2N`h}3USh{!ddOP(j+BlP_tQ1J0c;0C@xjS}2DktVxCCA+6j3Llt*|;( zT%L)1`6AuN zV^XH;I9Y*}LW>kb^eZno=NYw49G3FTxQhg}qu=HpGTC>TaXyM;dBa4(gtw5s>1PmlVrD?80m8oX(TZ?FgnV)Np3~CHG-c*gkblgERe?N7g@&>yj0@^j|fNKvKH;%E-tb6;;jt0h8_JQZfeK7usG0kTGb`t$6psEKlLnFonv z1(n3=Cv&BuV5x-q78y9+4iju-<8(b2kL4rx(Cea%gPW_iNoB88$t%D>O-<-Wiih}$ znj95FbI%796&MG{f_Ox{{W!TE7}~3;=Wvy1mib|U2eYuXWfhgZ44LK6ao)AT$?HkP zGGfaK7BwNKO`1*je+vID!|m}!VV7{ROf0kDhaLQuI73&YSVV`475xZ~N7@SWvVs#( z*#Vo!;Cc9i;MrJsFK&O>c+oIEQy#7JE7UG`Vyz3cLSbZFqV2g}+)Ok*QLZ~a9vv_N zQ?iDolXF5IoKtZs4Mftl(1d|$!4wZFl*#bulmRSZO4zu`p$ZixZ8O{qKi^gtvC^d? zgh=+gRpFOe(M$`G@YM@bRV5B_h6`sXcWUPN9!8TO2AJ;yH#5o8o+ zC78}ovE_Ex*L*6MX8(tfLA$1blCOui6*O-bpus8AZovHNolbAfM{&Qy`Ua|;Hj>`j zw^O7B#}hDoKwQ}BG_968PL+l&9RpEZA(1(Zj07h>mJKElaU4}m2GatWN~up#Vq#5^ zQ<6i@Lwf@eIK?C*c+lLdGMhBLvR{bLdSPRV12&}^QGk)h#4ss;yAt6D1m1v%`VcQM zDOGYzA_FccLOG0Rgn@+sfQK#(UxX8du}Bz{ILpy6RYsT@FEJ*LR-4Mn&E)!i^CSHx z5;?|aMwJlj#AmPE-MPyE{&gar(F;+LG#B%ua*nx5BfN4tv#{c!XOYHqFVoXijl6bM zedI>c!q@hE4gD4X=RJcVf^8Pd67g>W5_Wan|<0y7RWSVbf|5rg`S zBu|GxPpN@P)Wi5;_Fj>sBE)b_WvP5y0Aa+asv-f5inpP%U(q!$2VzE5mx>5a6f-5w z=80wo*3*WE*{g9a)0jtV@$pu1Z@*pFbFCA|a~Bo#$V+%00sAZJM*iI2{(Dhd_=`i= z!S`?cDoq-dez}x;{XAWd;3}!<=pOoa+|?sq(j6pkE|8*b3=GBt3zNQ$eyb<*rTc{-O6VpPJe|!JB9=kr(_XRGEGYD~z6n@<Aw+igp9c#VmT%<7O zUHd#4s{kDiNbq>DIYd#r`*nDrcXCQMnnFIzAmzmuKckB%=>xKkrJ91#5Ll* zwQ`?`z4D{|+y3~kSJfCWNJU+FdHi}xm8E)ebts8<*15kT9ugEThtU;*2w*G+DzZSa zk(lSQi6FppW|t_ZkKdc4Vo8!oprU%M1O+1E3-rW*Qt%cSK;d3X%5Tfc09Vv=(&NOX zrW1y?U@{@51Qi2=s1_C!w7W-8PncfLcAP41DkzL)9J*5Xl#af@AI7I@)rhNv>>?DR zExV(bB+aNNREF2-Wkm91NfBgSKEf9AKcQC5uy_?zTei(h_hC#VPR##-cCFG`^`&S3 z16VqjXI8u#IDa(5uwGp@eYVd0`$o!t0|l(1am0S)zchtw*WZ{I&paRg%lOZx0D_9{ zD`M9fwXAPlU)Zkqir+o{Gj+jjF1`8J|5E?@WQ^BqP0kmMM;c;j$kvwx4@71t2X(`zczlEzmxjRJU=hh*zIJc6)BQ@vWP4AF_vp=S&+q-|S8bucwr!kl zu)%Ey4Sc8mY^>#Yk9`d+caQ}H6maAHM`4a@nBTSRq)43H83;NJ)hSkrLf zW{?G3az6MV0rb-t+z_M$@X~{uf^k6rX<>e#C@!;(3^55)IX`q!T+B5U;z^j7h^Y;S zqcRWO2_x{IX23QXbXgQ|MT@~iVu~<03LLIcXCqe8!dj6)HgHUYMgW0(afKGtcPpz6 zRF4S#AO5CD6M6lnv_QR#%JAJ~OQ#Ib$%}txgu}})owh7vxn`y+eRqvRe3SG0dZsAY z@n0Z~{`!pmQPC^4hTT8eOHCT0QDS|s8-IRYDmsetyt57^b(-q?aqzyaZ?xck=l;&T z@c#RO6n4P>zxH=$;$FOWJ>Udxr&X?)76JEzDd97(!)tjWWLdO@3-BWFpnu>GiG9gt z+2BfegQU!^a6z0oR05n6e~Ku#tc`AIcAQelw`mgpAY1a$T0;Dq8c=z{shW-|ad zaPNNTZpW8`@!2^!{B@RQK-gGpzSa-NepRve02PrdPMvq9aLOOiE`hg=l_&g6P z?UsG&vj3#bKCxHiB%4Fn_59(l`|fS}v-|yXIZvJMPt?qVzt*h%-jbsvQ!R0dLSp)3 z9}u(RD=J<%yE>`2i%&o6yT6|f{q=v_=aPiaH-aQK4ui0!YG7>&I2k_(OR))!TyzSmwDkbc^{MhwazDPhFnq~Nrwc#mdU_1y7RX#MZO zLWKjd^-RpDvM7WB7cr~3D$W7XMX=U`x>FDs6_$W9WieXSe~u5~gPA^RA|uWjs-+Eu zy-!XbPX1(H!uJtM1TJedHN=zO^d+WJ^`(M>{qY#`x!2NhiJ~Hu&d+vd1}{fj$K$kk zUj5b9{P#_XY8Fld^C}bhd%g(1$O*mKgzq?=AKqWbZ|aYjF7M<~@N$1{XF#tyP`>}s zJiiqYK7x)>#wd@#nKQ@o@j$4gwMKZyj%=XseYWIl?BAua5AXi|H_saZJXE-)|A(P3 z_Lt;0!MCx>D~IQ?kJB`leUH2>nkcyWa+PRYzS;CB+wuD0=N!Dr(ROWM4jU=P&?zZ8 zWwc6uC+4I1BDHuy%&6#MKmz3e<4aiS-+*T*YK#Fx_z-n8#i@6uJvWD;cxLQZae>Ty z%jj1)L}BOqP%4)u3FD`L3Z?iVa!WFV%c^1P&avv6rPa_v=WD)hzeBoB;a83ZkGVpL zV~4rlJZ+ZH)nXQ^MK#Hp!zj@{AkA?MRa%-%7va zZ~A`!qp|1r%0$Jh80io<%Ip_Zqwj81DRCObqqFO>E!#n<3Qa#gd+)E0ezj?ExcL?2 z)@jpiW!l^Gx-nF=;e~AAt49^n{~CXVX45pCoE_b5^pNv(Dw|tti^}{N+0XM$zK!>H z{6K-7r+ZrAh>_D8XC!&6W29Ku$LItJDqId@p%<>Yzq=i3$T{hk9 zcLmI&o2rtc<{rG5m>g4j>HF99+K0)Cs$nd6iA|{S%K>?^-!g-(TH+8|t##_yKk!Wp zWs0HdkReSclZ9Fsv~%Owozs{giiLx2opZ4w+E-S zi^2{?&&zsl1@oxl%~r{-dXA2-^c6-Ln4Hi+$wnQi8^l&NvS3T4#Mt zpX3t)-$_JoCBc}A?^Pk=!{I}0V7EhgnbB129H-{ISlyKI9Px(vx9rz1ruR*Kjk1k` zk)9Smq)B+*L||QTO+H|nq#DU*Phsmudhj`d=qVb7XW1`R^U#l4R=W9Xo~aDlS96Xg zFzUe%Q<#Wd@rkx9tdtrAwD95#zH8gT|tn~A#C8$Y&M*zOXd zt#iK$krznj;hC6JZ7ePfzR+aN2c(A9*gdR6{GO@T7HSaY?Wh!=k;={yeiVI7sCH~Z zV`|IW=aln!%hF@``;u$!&u5lRAsp)~LN_~WP92x=hjnTxecQ331(NGoiBW7chCue; z@JXVe%%9o{pHT+Q5LR0?ytY5kR#a#UKuc%Tq?U@jh#lUb^7@pliE@H?(k=C>k~ky{ zhRX2Z)C+gn43uiJ@NZaliAX+VpcGN$VwOwF;3kF{GH^MI&5IJIf!~SXr~^lo7N~{| z`QI8lC+vz$Ndvhn%|DlAu3OVhUe#HdeWQz*k&k-+Yjc9}oaGH|8NGH%VyQY>kNSZ- zG=weSw^9Z);c+@GH@ZRI>|Evdts3#Av7N}+Ke2D8F2{CP*2ZSqPI;E@zpy=ZsZrH+ z{`#&edrgP6t=?R==@E-!;xUPkXR}gp>}zq;^Iw4^DL21KPkjbkUWcW(`CN6I*o1Wi z$Q`m%8mtWx4bRNBgWiPK1=;NWlsVC;N!q&d z6VzdCbl)s7du#8aQTw*sbdphX1+u__<~lfy=OXI1K@7ifuVxIkXnTd@_d0g*wD^&a zh0uq8)0#Cdu3x1V|K815U=45{gYQ-v_cbnTuEy>7n7Yd@N3-`O=t6WP;#Sf#Hy=eE zl&q>g@BWy^ZX=UZA8HapBK$9PRsO!CQbt}RVnxW(_INI+n#uMN|F@x>*COU?X+LNe zm`br3Fvz0c3p7;wI?eiOM7FJ?T*kGErKg&S`BvXYk{=?C%zqAjWLkYD*~n<(dD=bh zJEq%hUf%LF=AXWzLKV4l*e(Vi_>xqj3h&g!Lp)zLlUAnk*sZlydzJ8@_mz_Ct)`yJ zn9E2+#p1>IPHAtV>f_)cH+hwM)i+F4xILW*f)fT>KL29Jov+_V$AB&fOuc?`En_xZ zEzl$tGk^+*T%8~?N)-kIcU}h<=52k~EGm~DlY-MZ+1W@pgQX~aJuDqF=qY7ZO1>~O zbEKjHXQMov&LFc2Jzqv^NBUb$uxGe};)d$Vk9YCQw-EgXE zto4>xNn7us!!KA~Uj5w2cd?^bTe8sKn7T7kL6jS;0TA#%9HKfD_EM>z%qYN?u@XEa zE%C;_5hFu7@QBC+nXlKCbB}y@D3_)9CL`Pbbp{i;>2*p7Kk^hve6hE9Dgu1>{~vEYo?W2H0Kxf9;;6I`Q+rn^C`lPqaY3Fu9% zIxo`e?Wt>I603kAwO?x%QAlqyBeB8m;n$<;-<9*S=G*@hg($LL{~@Q%?7X%;)}d|? zPX?YAIg;a~L8aDeochWxmsn2)+RO=)f=T+M;j?)u0e>a_H`x;$9WL%m)!)Xe>$ks2 z=)sbDWyEw4zZW#eM?n#1Pt^$BjNeYShj^SGaQouOjCq)TbnDQmn3tCWaQ?oli64!* zvbZYB)??%rwZKVdchmY<7$@gwRCZEha~*RUHv($mn9RN?pSSDQW@$9l8Dw+hw~$ku z|3$4aI;q+4)^@qa_fYR?%xPCA^~+aB%UxowYq)KM^e|ppDtA8m?Sj}Z&K}Hr)k!>F zU#F%n#DX;CSOMBjmY9LnLiyAy7ZJ?qhXnp{C00sS?}Rppx<#FM+H7@WqdMxPUGpSw zjtopsf{56%>%qj7Fi)Rg_LH8~ozA~=x|0c`)RtSGuQY`PlwZ(Kwq)uqUSx`rDxpQa zn;!pITju z%@aRt9Q;`$SO0u%sK@Qx+2yD?ZZ%X?ZoD5^8RBT>Dq5$%_5IrH$)C5M#&}addELAX zXQ7K@5CgSeas3TuIaH+i>{we60AMdu55pjVVjz`C9)3N%Fr4AmIC<8acojRk{GD^gg>6 z`W-Py;q)a_ha-&VS z)cwcr$`^0Qlq&B)h0_X1_ny?akSG7vBnWLFP_$V0U@;AfUzWvQa~(7ZIA z6TXP$>9Q+t*b@KZx5jZcnHpNup440S%uRAwkPAaG0VZLqMBlCkh2V%%PgxEL;3~O~A2ic5Qv#sqgH^?2E5ilUfD% zIxauD9PJ!|e_L7@VKCb4FCI#~E%a}@@LQ~bQzLk36WEKOUz}WGA{!`}p%}3neo$0@ zRtreLMrY^96+fRZ0pY-pg(=Ps@1NNNYPHjJau^WF5n0+^eX8e3R+`L{hc0mAYWPQ?6x>Ql>JXAm`u%zL ziE4VAn+xtraj)6Q!S=*d$o0f`VeI3w0Zg;&ATz9&wx#ohM}nu!P2k%xcP3Xl)txo z`pRXwy4o_&y<(-8-8%k0_8CrA(2o-nWK-;_=C0m@nvJBB!Wa`fsI=|w?0K|6b>=;wAHleWvMVWXd|F1{ z*Lu2#kzkl=b4aC0nX)b4i&W}UA$9^g9+jjl&BBiptv2q54hK4f+s*4t|2~`uerTgB zGU5eQIQh!vPCGj-)9##d=7`{?f|w%+fr%6n!fL@$1_*eZB+ z%(Y$Zb!H@Ya(HDx8$hb!TKr{Lw84t@UOII|hgLRNP?;smr@1gOMKM`D+1+d5tEZFF z%D0b8)R-x$@25i$w_C*yv+~)f{lAdhX_6J|L(cGyewclM7 zij&dQeeIv}KZJCB7;$&lS|2^l0stoP^k*r* z`T3id>Z=NQzCWKkVd$VBTHs$0swpoLch`eyMjM-??lf9U^D?#9_s36d*H@A(EL*k< z3s1bCKlD)xk$bMcVB5t=Cv(EI!7@X`r|*FrE{{S}eAAZoDKcNZCaHW_{_Hd*KcHc0g?nyC^-f(i}i5g^9~&uJoBXQ{m|<3M9Skw~d0)iwXSKZYM@e(b znUCg|w&2_gTNDd=?l3VmpNGlCmbR?eF;^}RMQYy)=K!H9YRF>;063pmq7dQG@;p}M z-9ZB}A~?o?fLctU1%Q)`7lr4nD+dJ+CTuQXFbFI?^#%fj0;=usw7#S!I%^15)mKO* zfGV#ZoB8s~P^uR%ew?+QydI8H-EwR%Z1Bic6GU?FUt2b~tH(~Xnbr+ZRnC8yNgaE# zFV`SkqcMTcV7!u6suo8Gz7Tq}`_=fgPHJoSWX}1HcDic2+8 zsLn3^^n~S`_DvM70yNy#S;~glAB96fL_#Gt1c3LKSoGT*Nu3Zdn8p$R{4YvMNO65bvz$>8t88yVoE6FZn&;SREM+qD><66Z6PW`S~V#e&6cC$qFN<-4Eq z9NP5YvWrE^tkqE!r|rN0yhy>zNXJZ*p;NUL>L4e48H^+WOhodOJ@9UxBmadzm$KNB zT}z%|YnExV3S|)n;EFJi!5Q$F$RX@_kU+?K(i9v4ldw~EB;vGhwl6&eOerBM4;?8O zpm2BR@n{C_*(vi#b?H_Zz|HH`Fd7_%r^qu5PROpE86e_ulX4?WE*tyu6xv+DqswW) z6SI4Dkk#q(DL>KBmvW*?!6B0M_bHE19=?jGMG8mcVWm-WDXVvRrnpKt@{xae63eD7 z6rf&2UZw;nVwG0>g=j*@O#Gw`kyFZIrQrm z6A|6m%IU9p2yDg*(~Tc5na8)m)s{+}@4}r@job^JXGs72(dAziGW!m(gy+lqslA_%nMD za)KR*5>r7#&?$8)U1%Nya~B-R?uEI-EuUN_WtGTA>*`^2o7GL(yP~>+5EymR5F|)= zk%q)RUYjf7aIf?G$tPYkSC6{EgS1%((Pql90vF&h17S4hsHnGbv&L*hDYH(&+nRDE z{W7-aj<+qMipQBJlpTSayyJoC9=8_-0*CM1Z0@W#bV`SVXtU%;@vdN`qL2M@=MRt# zXAHX-+ZZCzEEWywXtfsV?+>EtPP*cp1MA!3OvNMVz1z2EHrCGk{FhPq07oJPBuawE zv59%aVN-xpaB$uxmgJDOM8}E^gkgf?f%ZYo?98A`9Ml6i1vV*=l4lCVjf*|L=Zc#20^-p!BJ-885ghzfDpr*Mg0WO`d^`+7SF?H&HBt&y z&GwnF;=VD&|E;;niKmw(R)_q!T@@8+_q*^hRb(q>>`GD7hhwa`>(E`gpr{6J|G9aG zO~z^vVn0E}rESFOziyrN_SfQ)s=<1~ZuFL#@mhlBVgN5@LDD0)RBO%LZ?D05VRi5+ zu|z8*^krAd%R`-QN4LxGUY(Fp?Mq_Uj4y7SK!rrx-+ooqIwB4}5{_z0CA>tApieRg zYM(qL0a=}t4 zX4+x`W`Io~7gM6XPKOES<(RXCFCrQQV|FeW~q+ zo8C|meVx&Zg^q8*yX(Ee3asOoHf&!hx;R5QLT4rEJ;ngJ*=@C8ckQ=@q ztChQXb?&#_C~n{HFw!&f)t>XQo4d(pltqe|CY-yUwg~%yvR5)A5)8ze4Mfr>QYN)8 zg|%a7BdjU`$ zs_=L~xl$VlpDfjKePI6k(9Ygwl2I0bKg zuq&KX(mmFq7Yj`kVrEavw?8Px{%HvdTYk#O_16!BeB zVUP8HlfqZZ@2ES*%65ns5!e`UmtA6Yin|kqq!HFOuK%)2&G7rotmAzd2FCEcycAaz z^QH51-}iTO-sSo*!E{h40zj|-XzuI@Kw@Bq4*ZxvYvejJjJ?}Blh>XcE@1^Es07?$ z1&V<~h#>^uUBw{+2*lQ49U=IsWAY32W8t#+v#~?z0NJmWR`Mh)DhPBnH?AY<2o9tm z4YYW0>Bx)R9TOD=4AXi}FrMqU^nbEb+57u?hN|5xiD1KGYWFNrwE{)B&-avwGA}ve zl24oisu4XJai3kr;Bj}_!07^SfR-kAdz8PSpW79)U}Jto}c?r_9{C0?M2Smk5PuNf1jo-!K^oq1DyKYygTd1b&D-?zY71r zz7x=lgr!0VVGPkEVUwP)+IGBnPeTS9{DKq?LH9GR$rQfd(MHxf3cy z)z_?GElKcdd)QXvUp`i`+&J&81-*;JE|b`IP!HuJV>^lDjvfPCby%G_*d)dd_LX9T zR*RNvd&fVjmA_kqrkERQK7zjs8{#i0Go+{^5*er`))itMj}pCn%D?`u8Eu*Skt?`B zmthuxGvMFa-osS+I24GU7N})a7MOoiR04mJa<>}E{_>>ioml@C-S_V^n@+Ty*b=D4 zA|^%Kv#;m6mI`nJA^}4|Ba>NFGd9?PNhl)#ooz`+s0aX{N%60UMPQ@=7#1%aj~IyO zB~SWL7lzp55HgYqLYG0QEb(H@_Xwb{g1-Y^ zIE?4=+R`wN*!nMNJsn~V{a(m_>cvS!ETmogh0AJ@#d4F2@k?$JN$wxB_k)^^+nt9THnz4V zSx$q!9MI;h)GSJC%)nf^wUM6U3t*N3y52El>(@rx-c7=7|Iq4PV#jNom#^vbGS6Lm#X_M?IfYh@^G#f^8osh*z$3FhX5_ zs#6FoS*Lnb8?98lYr9gWGQM2j{&l)fT@ltI#u4J`PojrFGIm&umqwch z7})DBj?ir5|8Bt>PtTCJD1cug0p`hH=YfUu=NYlX+8J;Y1ORj^*0G*~nnQL_8_h0C z5UYT;Y2*-qUuru5KTC0-hr<5g1FslB^xshtJms3MYy>i@j=gF`H6kE6>@gKm(dbfQ zAp_d6ZNfQ7mlRvEq(VkK^$yDYFf*#(n6+7~O@s0y z^WoFt`~CHfVq=1}!TW-jNT<`l^wSH0@xU+U2MMqk7E&+k+EU5i&Mh^xD$8P{{;yv7 zFQiWq(q{GXAIKT6XbTKA1nyENnxsoNYTi?6Xxj>og@ChU@zub*n(=I6GNwh$wB}R( z8N{-?4A#!Wj4yod3bTZqsG9}AgrsF0LD6gs;Q(aBE-zNLcmfnYaZbX97mTmQ?@2J2 zj&x42jvNpX;t?+vtD85ravWgmZKze{U6OMlNV5a~7;v~Vl~M1J1coOXdd?=5TJl2{ z#_9h^Kz#hBwoal49oafhbCSz=6FDZheM28&Xb70^D^dUI?b?$JDv0N-HM}p=Fy5dc-#U=vH~Xa$nnbc{F#yY3;<7TyliYwFSYeQy1MqnuqGCey33qx9TD?;B9AR zsmsw^P^S-FYO5>jPyEr5l`U?uG|(r=6#=3}xjq6|n{=7jj!oITCDJ)mV+RmbLL!cI zqm_RF}gt7p;NQrpo`7$-0)njxbK=9LWQ;UU$V?I+D-@OHJz zpdroRMn7H7Bqf&}fOA0UQe%U{1%Pq_%)GU%emYCMR?-?ovMA`7_3t_TQjzPWheW z=?s2Ph!-AzkLQ1y(D4jKVRtb+*l;8}E7L7;4f~V~*&E(gI1rQaV;d~w43!9MY^wPy z7L#d99&rYOp-v_PK9)s%iI&VRX~R|K#pM#T`}A$hPb)$JEWX~7Y6$Ha(hvj>@jz+V z&ckp;!UB+Y-ep)Ll`0lqw>r*ncdRDIs6|?3!_cr2>oA{O`-c~i99`v5pJi?5Q30OF zQm(bj)IE4=dNIKtYBA%DE40v;&xUG?c)`?R3LDNTbv71q>#BaoZmuJlEODItp1IjlIuW_GeXiahKO|@h~b1Bfi1{CVuZR zoY{-{SL72U?4&SD2p%!c6G}&nv*otcxk`aBm?>bD!v?s) zoOXf@&9bR6qb)kk-GH6)NL^85I0-~P{L6jLvvLYKW#R!M!Ay`{WcgG#3?xYaxmU_I zBbwR*4_x{_Y#gpQU6xt5gD`^}w=L?i$y7JJLIZlbF%c{3j#BceNGZER7z=LYr6#tu= z4bh497tI!zqJP!Ko+VvmJE*6j96^C{U1q3p?SDTAQ#&MUNr@91ouvKrzVNl-%_j~# zM_Jn*R^a1<5+ytl5I8Q=@)8SUw%d{XB%>znCHUPayv74jtFrvk{&IIDJ)RW$Rt%L` ztN}FBKd}GHY@)^Gl2Vv%@4ZU>V@ zoCnKmHAR@hL;m>*3g8dzx* zGiWKzLj&Ux#91%`!_mkC>&xgLsT!=(YCIx8Vt|&OFmF)%Y&Z0YoTH@(83cEtN4!%K z=@!R|LCalL`IH(lV1RO>(1AEzw)rQ7i98)A<(Uh|WB^jEy0Ep)-6@%@w`F-jq9TJ_t z_VAe%02u|>e(l4S?7C5-rX6|e6n6YDD?&R8OA^b;8$Q(Hf-MdrmbNzHv48D7XDRML zN@Xe0e4ndQ(Rw;uhb{{-0*(~8rHCYCAkr_#>!lShjxefk5Q~UFkebjBPK)^gbmS-5 zH`x=Yf0W4Mr995sjXZD}M&B>f=<;J@b&RXke`&=c&DRLY6f+xYaCXr}vgk*aCN`$n z1<#Okzs4SnRn zyf=iN<7b}E;GEyZ4VJ7A?t#JFIBNF;x3vu`{Bq!BNi>OE{W*flDYaKgw|mbyHJ+{89^HqT8@_da`|HZL^?=C{ zs#P3HjW1Y|%EvNc9k10ZbEKh<5S15kwRj++_3#Xh$~Q!zM3Fo-{E>-#P_Py$hKn0a zO|XLkD2xpntr3c7zFlY@8w&$qtBsqlIClU^WE`l0aWumhfRht+H~|E zAe)6z`jbV_#qn8*LF}XXil|OUu_qFF$d98{89g>Zox7b~$fkbR8Ru8n{KQ#mzbcvA z*|hYTsh*`aJ7YWVg3SxmDdw2=jb|2LlGBvY+x8VwQF1YHu@>1C8*8YWdveKe(~5BY z(%ak6W6_ES*Z;=9|9zdo5Ha$W(K$cx*s1s~z?u;rlyi9>#?P^v7-)=pe2*Lez#v<@X z@2qy{bcPL#(DGp_sfe0v_c01g-V#^K`qqBo(Z-G&x>eZaqEyPZX|GzT3L1-m#p$ z@G-{dJ3=G;j=Xutavr`w9m?LF9@{rS@X#)0_OLq<)b6<7Bpx_o}C;ouK+cHMfehLYOD zdB2jxZ`G8q_We&yMhz8b;U6U0bX^{OXp!i5H5^Lk;GAhr84W4xVTu~+H{=LT>iP9( zeWmtvzq>XMnznY>Uz61QVA!x{YhU}~kJ#x&edza*jKj^J`isZXhU#)tWCTgGhRE3M ze?(~K;)~iP(n@lFCer_!;ej!rm`XAr3?f8K3&W>jW#xn2?I+-IR^FsDc+$`b6J0P$ zR~FO+f&m`cfuJPKtu2tlAC_Ewq(H4r49EQZzC8OAyO2SclW*+VKv-;cG6fAp1;nbb zvbX`iVO4K@{eot!)WVV#uUI}MJT1-Q;A!@*jIB%jmEGCuW|{^#v$D)a``*y(M)0uj zlaavo!sOyfR{jK^shZ&6?y{HsCu-;ZeJ;0CK8q7J+VpQJy z02~~UTMC6SvcdESVu1)W5R2%BVu-1swQPHwKM~x#K^Uzi-zn%Y*O4tqj-ig0Ot}<+ z9WP^`n%t%*HQK<(gA~(pDHsV107j(ByaLQx2O>v!U;4^=4giYph-qkqstCWRxS7Ht z7fb%9 zZDF%IXB4NMf(Zy1@Jn$le>jWK#{-Wzv-2{16X4?k#Sfx05yHU~hs4<-^7d4&mc~W`}GM)AXUDPcJAB@9&d*xvyAkq5>wS29SL%G!3QCx+;HwxUez{Q zy=Do0yzs?^UYR$M3<>)VlU)M<^s{UO-i5i zyZ%AC1h;FX%IE2zlcU%O{c}=$GAO$&TTARI3S8q*mml-Zkd*yF1cB zBwt7>*-a#SwYzywwbCtHAlu<`XDoQj$?{RcXCwZ%aqpU{f68q-eegKyNnO#)dFS$y zJ5icYg!JT{{XX~88Fkl3f;g3W|6MpQ+?s|VNp)ygIX8af2tpP897H^eekUeTs9Sv5 z90o`%#6^?~Wn$^oe}Vvk6t2`(>7oqTj*+^YS<#}g%CT|J-s`l1cayA3Ym|q_A~d*D zPh^SbYdKYlSt!n&O}yA?D<@yT*f$h}l*JFc`y~UpDR!lpDf#AJk6qc$n>y?0*8&+g z$E$;VqC}uhWga4G48Nb%zunujyY(!q0pow+@0bp~J5KsO;QTTnge6Uoz69pd-hD6Ip z*!>gMyE{{s;3euvTVjfj#LA z!GU~S3GHOq*UnKrf_Ub66K{uhJJ`fTS;O+2+l+aEMbYyf _M20Zh71JCfad2zQd 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

%PLZjYLcfphef(=4(-2k> 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

mW>H9ll)q@qp;a=QZkQtcC)6qBBdPg z30cJ&M&;A}{5B_xK9G9#giLJmGUntsWVEJEyr();;Ukm9?Z)we>Sa7yg!pWj zampV8s8b{lN3`8;R(zI1DpX2;5^{yk6C{ZS`Sx@nTosa=M68{;-aeo}d(_V+v2W@T zPGgL9fw)I$k(*}VI*y_w`20!egRBR{>GFT=-#Mu=^q)Vln85UssPSbrFf0@bRlBV*ucW|?9~^^#&$GXMpANBTD0`pvKjMqZHUkky>})i zES9EmRoH6Y#8vA$vmu_hiK?{wJjpwT^W<58<7Q2H|9_&e@!&G##gm9^Td%DL5^z_T zhxH=Cqx&a?0h;c;-Vf4kGU~Ta1Qw%yX&1tCVUn7knE`r0(?LKQKqXiH-K%sn3B5Q&W@1K4shUvUF|~sOh|XEnQV} zS95oJ(w*orcjKvR8S?M1db_XG!*(9Q{L9_FNk5%juxJhp3VP$eZDtE8YQUE#07Q^eByV!{_v}E@y&B~tvQf1TDR!c z*&P&3is{*4Cf&(u#oI-3NEtHWS@Rb9^=-&-&t+-wLm~(x5dA~&S;|GPwy7#6wER;-dYBgM>aQp}p4UG8PlS`O}Eyz@AYbPY( zc(jB!`mex6f?TCvGxldc=Y^zIrl@xo&hCo=L&jK}_9)^8ZU}^f0{z{=JhaNT`@<*O zg+^NU0jivq{et^plD}7f7rZ+Rb7~6@;BS9ij*kd-ex+RIl?ow7hl-xhvn}3;$;S`% zv#=4c&U3!6@cE`%Xen&1o}FF%X6+c--i&nBdG9V?ebRWwcWkjjx_%0nn0jU4g_YHG zLhBhc1~!??`hqOs&%mfP=?52mVc4zSa1Oe zsari|`He)=hxJN_&^y5jy3bkE@hjA3C+?3E$b=HQtRA&Y-v!?tzqlXoxUtD(&nF=18N)sz`Sa^Bira+UN!_D%43OtbIZP$S!2Or@h_v-gVw^<7pq zWA)cf%M{1kLMkPzE017FB>g;6sJE@DBp&cXA+bO@)l%Jftg6!Na~{T{#i?B-S~O3r zlEsquKaW$IR7CEIrMvKgE8h*yRZ=@Yb5m2%@&a<0`bWJIu2?f|LgQr({w82R`92Gr zcursp_b9qB-a&|rXcUt!OIDty%1YG#;ZZKBmh^71OKJJrzy;EN-)O~Vdwmm+sAJ2v zgpN1&2e-4@@u;?z%RI3;ZLadGybf`WFHxG*fKF0br+dXO{|EK1uYbH=deqvOEq3KA zo;3GWV0@st`uOwm?X3TwMSq}h{%1jl->O4cWp-R}L|6~Drw&0}^Pec}yu4Tl`V?`W zyR`I64em%f=vK;~Gn-sDUUefO#coX;P0�kq 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 N4x1!li)FNO9PFUmg)mX zlB3R6cPB)y2}VSAot!Rw*1@U0C8=8Uy5__G;-Q$_rTlZo|Kl#1eP;aQE?Mdd@~@L& zTa~4H-3*}r&jv{N`ugr#bnRx_M%Uu;4}3ZuU&HbPKEG-^Xl6@~C&)=oBgWmpoupFy zmNpm?wk$zBfWl?SjZSoLB#siSLHC5RQq!+sAwXWnCMlc9$B5t4~zzTzbz!+14{ZNfiatXK3 z`*<>8NdgIlWDOW)A}ekxa-_5)0?big)x@vdcA>5)81HY7>g^ zw&jjKshsFoR#8}z*Eex8CeO@&)unvYEFglq7@qU6qWLf_YOJdnV$$^P7>j!LjwYjkJpTGN? zoH`4e>AAc8te2`*!h*A(U(?UJj~spElD1Z`dSfx{QnJvuz{s0D?U%I!^Jg0_D_nDl z(d#hh5D^Nj4lNjyY-2WhXsylbTq4XGbwu* zZXfa7_2W)%zuH*UN4*k(A0Pe0mS#VDMP7OSlZRV(<>q&TRq;@z`+BF@hmM(ue7j8RYhS ztTsEYW(?V*o^L|F`13_?;j)_;8bIHy73R!SllCNZ=>B|Kyj1Ke2(wZaxQ%^HjlGZG z&87{pL9wKNGlj1J+e+LBGMWr=->d?j2Lng7Zpa>c2EeX0tmt~G;Vk2sT5PQB0E56xEe65Zpgw#$!vaqK$!se&uD+&1hh&A7 zkAS_s#;%G;WxQK4gO7kykf>Mcp`_a!;k2oyo~?fsl59OFQt#4}0QP8zW=-jGCkM0+ z6F)HWUSGtxLT9Ribf@lq`LR-4w^6HmsZ0nFFZ(Lh;W@uE2Udrd?^XsXO0cFn;q zGZ1|IyOj2$ti4mqZR2M+QdHy(zTFln!C=3-dtk7l9)yy(_@PI9RZPpE0f@4LD_V1e zru5j<;5Gs@)=yV}C*fRi3yzsXNSQ_ZllZ z&FQRmzo2jYutUFU$j$|;c^|RU1>R6krK8h)?_U1*%V{R{q07-l`OqJWQww?acEphK z*H#DrJYc5fC}Fid7aq^FrIn7A9&YUib{)>D4Tc=-9RB#UCjH~!)4_#*QlPfz|NXOr zZ;N{yAB^`s$hOGpXPA_e7t=q=+gfX+Me}LMq5J&sj}rj_PJiuHB>%18aW64&Gj-qr z?|HY|dBvYj%e;0SU?r0CsR@!LBy#~1F9_sl%@vDgTS3Sw9(t#Knz^iw$bnEL<+TSS z!j5_)9{(EjF^5dYB?Wvd%rRT#&I7KDBA5Bg&x^qFqJM-!P*7O++T+}ntvNMzSF|D z4;wZPwjbl3|8L|D)}21R+Pn9~^uq*h#piga8}3ov-37P&%})=(H~l6twig-;LOi6) zNIWKx@h*!(xjV?JyxKpUhC_LHKOg6-lh;mxs*3C{AWkwoCIgRe=3h#WH*4nmuj3;J z&f}$kP2?$4zu8XdktBhv`g`?`QrtcJJYGAWwf@F9ibIv~3QFG{P8lLqv`(nqZBTL5 zR{A(0ezF&jOVWE!>+?g=Ss=7x*5F-0r5Bby7;O$mAn|4`a3NwI6)=2aqQ?*#a91%l z1!Et&BZ%Jld@NW$aS@(8*9wo|4hm7?k*f5&S7crpZN7JPFAOEq{}qJ?w|}iTn!-8@ zg6FEg5W{a@5;9em{zp@|Che`u#1sPdT+@*xyvd{ynzpp7>E2LAE7iWu38u9eXcsD( zMO75LIQFgV3~a2gzrKCl^$_kq@%>ZhP6MG}T4LKa$|kE^2KxK{=T9@LhYO)SyX(sv ziZP3ScLRK94|EQXFAs)x`|6xsDP*ARvABHhG;DjG(<$}3#P`_C>F!DNgfvJ=93YYk z2_~^&H9Y{1!ru%PNeCj9M8c2}K((~TAoyKI-Ig z+sqSZhV#q3w{LR(ztt}vue|=tADZC)N1DghC#_XMvj)2_w&omo&R=f+L6yUTlXubS z=IXnB6&KR3g^BH5^xoZwI(YBVuyeRQ=1D6%DJyI9t>&`K%@QmN_86HETWLx!p=G3s zN#(ny=+b_NVQr|U6cP!m51mT|#yJ^kgZj(JxYP+T!knLG<+kw$eIv*7 zdhS`?in`^E!C%ydb!9$_0PIjQzMln3q}ZAf$G>7hX;27?p;?F%FUT!?kG8;|{GYKd zP|jU-%5SsL?ZEb&c=_`S>QB2~{7JGlicyJJ`v*u+c2~w3Xj-1df03!?~)2$#D!MX$|$M^C-Jk#MGUSdj9 zoN#Jl1s?>PD9VXUqxJ!nIlXc5_zxbvIpl~lVlXcFJinO$CpPvY^n}vDNqeG_i2kB7 zK;Z)!42RnDbMCPZO>B2=2;8q%L2x*vrt6+wN|pI){G-EpzO$|BVy|t(#F6T8#~zzZ zQ|I!|yLbO=plL2qE{0J974>xvb(YerH=b+R4<9}GaHz=e=eyRP)f;0wf5x1jM{O+I zLqru#d1vL#-pTyLvI4kRlmR^-Rdt6hg1ari-RY=+H9@gvRkC4;6kUp+CK}=&-w36j z;h~$s>3nubhz|$NNE1S`^6Mpw!?Ag2b*up=1+c0_5)o923I!yUi$fszC|2Fx>I7^Q zq6~}G0>wd0@6ZWKEO3&;tREZyE4JWrDO_FZ)!0HKiP&$tX5&&o`$hcmdovj*>$#ZE z9&h}%hR}24O_tu$Te~eKcGao?lN#f#*7z^iY=4iOGW%g=<*V!q3?p#R{Kx3m+K*)OBbHgMx6Fw`@O6`0pnn-5G1B|>JnJRzSF}^vz@*b_V zvS2;Jtv)bbb-8N-4ozCAyZCMn(bWVS?`dGC;>-PZ)iJ8)+fNnOC`cw}p3`2=?Ni!) zD%#|xeaCjMxTrYw`KMaBcMCj8u8*ErCE~i;t_5nIIw!bS*kE{BKHTRUdS%~x$A3BM zv8ZTdu_zN_FIF&xp+>n%5V~Nd_`A+5gA}2^gCD*`w^5Q zuYgB^HBgeQ59$%cK^}k$1H_V0kj%6SC?Bkn)qqrN>!#-Pb5hp|9A~~Q@N57IP!c)I zY;4(3OZ}{@<_07iB{!U_E7o80?))6_4of_rtDvN6g!o{wCkmiKK1)g;Z=yZfE&H4< zVSes~G&lF;%{~{!D*agwE;`<#yH_(s-bkGTsLYy+$}yAruwGtxy2f%iSi;2Iy`5H8 z$_&eUSR|{h`!kiC(Cw*zBxo+~m+~OZT-PUb;jfFliDf|SrR5-_ZmF`(z?!#U9lL5> zLyu4Cea>b{?VUm&fsoY8pZ5P=-s`X7oxA60s1p^Hje?4yz%2sOc-o;NPu2F*vY)3P zNaM5BEj9q{IJa0Qv%oZDC?c2xv_dO2CaU=>gJ@weh~J(U0fV8*Vl2c`jo2-|-r~wL zR%}==C|v-ij?Xk0W?=cy$v_|I#{e`V00h)PAFsly{N4?`D`WW47IO=EA~jH^h84nK z@C%udVd_3>qj^ON5ne{@uNC9!9SN1i_%c8H@O+v@=4Y#^(vS}2eHOFh{%J;1tDd;$ zUvCCnkhzb*l{|+e3|q?+#8695 zH<2fWw2R*-=|;x)4t9zIcU?}inWw@a#gdQQJqTpReFokN)gnQsOQ>{DlrKk-W&q5cM}!G17<2e z77ZXy^lN*+zM-RVso?tmf+RoP-g#CNht<_Tu#Ac^rIL)XDS#=>|1*7|C8ROn zNFfrDN6(PLHgSE4LkVKVSp39~r3w=1ek!S~METKLc2>ZZAq4a?en16diSJ2y-77;x zK{OIA&TPoW^%KQV@fMeAR2$R#h@zWVd7s>3A{G=*rm-Qh4VoSq+;Lq6C;6+Z$+w{K6{Bfd>TmvGjOm9ktvyARYrFA~4dzJb+ zYce1(r*1yi-L`%Em&Glo)!Jw09;`b#q+NLa_#jl+J0{}$&!ks-k+rSQ53aQ||J}W? z9zAy9_v^x+Y?X7u!ES-)``<=i_yPv8G6MK`&jy8MYz7_o8kYCejZM1C$#fQ^-Jjt8U(r%reSjC18N^7-992dCtI z4CQ~c|5mZ`w0ixK(5(F@@5S5$$2C@!{6VLepRae;-~5}?(eUwSGv{Tez`Vo5kAJ;4 zUp!yU1{Fl~gC;D&3=OK8CZ3RM);yrPrh;RKVXTJ0>n#0{%{66H9Pd$#2lz;Umlx9t zItVPY2D=edB}%0zdMd${UtxEev{GXuRS81#pTv%^qvN(A&{Q%CJT0A9te%guC}EzKhKoKoUdK1~E{ z+}TA57x$*JuM$57B>1(P1-w%jc_CDdP{{X})gS|SGRB?AO^qEKlCNEPYiIZ9+q3?3 zA)R<(j*wayT7VzIj%io z%7l`|;w~);NA3qA;sb5J)2GR6+Jy<_$6oC-SE@{|fzuA>*6!~Zo$bh#jD;SZTU{D4 z+7}vn{rW?#3&r+$xxHcyUOogmOIkct-rV_NK~UA`ggT zoWUUFN&4g|k`y$DbR0NMGND9~#K}b@HK-y9AAkSBgA*cB;{5#becR4XP; zRoyjS6$h|giXM0TGbg0jFThNY@|?PQC9f)wMUlMPq8^iGxgG!2fo?vB;`jZ3oyobUZAqv`Nqe$SR}KZsWzs zmH~gj;=REnqf*&IzORwdC4xQ!2?kG)88)OREQVxPu#M|GK3m_D#|nqgf|vqHk~c9Z z9zR8S(BkA>A2|Zipc@N44>ra62cZ2?X$aK>Hhz&(H!yyZ@_~~#v7}iVawr7#6}h8V z9&+AFM)iKT-#uK)EknwK%uWaCXA*`=H|n`bI|kA%mRjskF7ev0RvywJeTP>ZVRVv~McVyH`>K6Yp|lY|i<6^qIv`BPRU z(|r)+Aryu7oVwbmo__O)z-5`EEky32UTIgJR{E-&b`em$g|s=-&W&MuQZKGxh?8??u5dHZWX__jUGZS~^x z_Or?9<-dm$&)&XlXC|OTRYeOvQt)ob&kb~bb$HOZczF2EMW^#C1S)wv_7htvZSRe- zGMJE=>0`zxS;RtPiIt>h(+B{Bn1$BC21(?ZT|z^!Y`EAytQy%M62zla`Wf7GA))hn zm2Bs*cL6r{vijjF8l4Ok((6r@=9doR|Bu~>)4<_n-(4(=a0Ko6drSzg?Xt*?zF6tl z17opED{uHSD=gc2^{>vFrCss9V|~-%m}sOTFEd;;F5;s2<6CEPo%oMDjkCBraGQ8P zY3XlqDW5q%mTN>Q)1mU#L`8G8b7|$HGKYx=YKll3Q0w|N8D~M(w;4 z{MO7L3=cjp1TmN73R&yFQdLG-(24+ROi4ncxAM(NF)T;}q8%QOC#L_Lf(GOc6Lr(M zD~)*K(1Dq~Rjj8+WM+^b zpX>XAv@n?S>(4S6XX$Gn#$d)_&EAf|kClOeX2tQ76q!{`Ugg?wJ zWITE#Vsv@Hi!o7iUFfoXVqVI{MXn}Vt7_P?@AA8f?TMIK`#+02e`_1tE_82vo#t|O z;J)@?`_BzvvT~$Xd`Dbud-r+*T!oqBba(O8Zwn<8FL19L#^nQ{8Ofc%&U=w6c0*Fp zcA8h@O@zHLU#L*LwRJYxh$#?^K#_?4R0_tOV&UU~QlJ8msYejS^i-sf5Rs6?7yv{_ z%QQ8(68>A?O^5uP4B2xg#b`w#(F^7;Gi+{R%hX-kHlGt^`PYDsvlA_y+?6LaoyQz* zw9g)mj`OmCO02gE!oO#5KN!smSCn#<3!(qY4I2_F9h$(EoV&kz7&Y5<IQ%?8sg!-jt4}lu%7^SY-+~ zMlZib%^M1NG5i6~o#K$-dx{<`;K7Xt0dG%YrvEgE0f1w6p99?l80tLUcTOqNKJRm_$|2RD$vjdn z?S0!Bmm`@o=_WFbtGu%^Wfxs+=Ig!3F9ZcNYSUEc-!=5IC!_sptrJg;zPyYAZS<_9w9rWH7|TtV_p zdi_OitqL!)cfQge>8^_A1gsrgFInU3o(PB#!E2&g5G&9y%$i*U<())KY;nNc!Yx&~tFLWc zW}`>X9`0wY+#XRMyWpv{FMr#4we9&(S!aZA+D>hN%evz~LgQPm9fYmPKTP4htUnM= zKaZa|f#nL98<3Lr{6}6o*c{e)BSCsmZ-1#+5IS_kecbm$GP1}2gGaiXuQ{vc#rD)8 zt)qeH~~+L@w6mfAArG5zzL+TiOv5^&Z1%CtVlD+ z)CVkz1Aw`I-1OsT0#!&za7cU!QH=-m(}%_(g$jEIbOUnnAdj>N^BY&gMh2 zqcx6FjyvT$J6_sWNv^HP!DUUqp{ny|&-d-^s~|4z*FJd^CUfj-+fC}Z_0Z7WoyZ-> zfB^f1w>6EE+9@V2Vm!ye`!aknhSQvBYb7L-2!S82uYpTf&W>J2!+61$w*7&ndP;|I zWpuhAw4LTlTNk$D# zwj^L&){=)@4DumC?2RWp2DzL49*kb@cnDM%1TA`(Jn$&eA0?NS*fSxb&_QBE;`ssl zrnD~hpPVxK);=LK`5RJJy|3R|-V_RJ|Jmewz!s!1YAzC_xYnSU;L-A5{O`O%rj6q= zX2Uh;O16EcOpP-n-MphPUr7BLbadM_WOc<}RDC6C^@!@cQr~*xtkV_i{Z;iq`R$yx zKi|G%rsCsGdbqmV)>rKJeIURP>H2Y_lz~g`ZNidVR}8}6e3QZ^Bzu~03~@o>?vM0V zxf$ssqa$&wv3l0^Sem+~;H>zyuUMH1-${`K3PMkY)<+p+0C0>tgbOVU5k6i(7C!=% zGFG>N6#e#&Y$j~B8FWlIrts7D-p%)IHCP`lt|`}CU1gQCUNCdvX5!!B z!h(=5Yq_1ia`yg#qq6#~7q7ki`RLuhiNY7IooTCKW=;6cQth}DO+POrV~*$lMuw5a zy!5&oA^)wt&b19~{nRv^Ln!Ka9KE|R{J8FIN1$fVa-Dm2v7eL3NrMM`qS_9zv)LDU z&lIpzoT#4(d7ep5>CVyEJ(j0wlAiQ$nXf6oqv%xXQ*ycoRv{KgN#v(ch_8OFyuuvgd^kdm9 zGa`tpzq@U}a|S{rif1;d`$G4`r$eMqIXGa20UCnW_=8K?pPLm)23y z%9Fc;rZ{Tmvg#k1EIuv6(Tq-y07W=MIS4`EBC4OO=>wR66g!$esA^sI;#2xfzn7I_ zUy?1nG{MBwvG^^fnLTv~?~29HJ>1prSko0lDc)xiS3ps z24P99SB%{5XmS%Nh{dqwQ*=?^Q^zTx7{Ef73*4+6a;J)>Jk_mmJ}SMr1klBc&Dr72 z&_9YOe?eEJ{~)oWoESjC&<({$ap1<3Qi)F(dhik%XbDlfxd-H7?+{t^Dd%lZ{hsU~{cjU_TnekBW3~oCk8V!RGH_=5%L3*iJ zgoQj7!Gq4{Li6y7j*Dx9+_#oMX+oYv%bQRZ7#}yi^Zf8)Zl z`6?b4+@QxR(SX9fq8rxvf`d!ph1hG9?+qff*FWg0Nt#y%o&F^H$e-pxw$Q9x9?1xu z{XL`g)N5Z{a`x+okLI$MDoQ#kuNYgwmEE^C$|PN2$&mbuiVc@{)7oyO9tu62Um1Iw zb0$W8Z(;XQxO`c9tmwj_*Qw_`=`<~uPRfb6S4?vA#U3)9Jb@56hD^41!nCu9nB7%>CcqZDwfmMR! zQQ`UeRu@9y+iTKrKD>h|KbfHKSew2?BSiqLzlyz|DjF$qK&uDN1|}v6ioU0q!tiE- z*Cl1s;L-0BJyaD5{pSJ+x9n2qQrd&t0wnPChtn6Fzte{ZPaPW{`wd2(UGY8LQkSE; zE#q@}`C?pOfvh8Ae!^GtuWwcpebr^vdDivY4EX7iVcoUaoi6;rL64lqzO&=};a<%4 zts1Apox_;JyFK@qDvraMd)uAUKmWXM2Jk%KqKvIb@p~mh-cn9vfRX@gnSGK4q_BV> zJeI5i74!mJRoErj$u^`pWCe_9l=Dl`>=kwVfFg{;ZTed^Cdj^CfEI>?azUzaXJ}08{4%owbyG< zywGZ~`N8#hliD!Rb&#sYSb8b1cn39vpctKI#Y4qvxUP&e(Hx+~6iE-QLRWxkI>8+e zUNYJ2E^+Ujm~`A9j^S<*s^T%@9%;-YuvFkxC zGnSqkq|S|_g8^SbIn|6(IFuPu$DKT@!rer$OMs%WCcVJFqENu~>ze~JhrT~}(d;$; zpTGMH7g4TD3jHaSWlZ68gz2+#@zDTqnT7pqj$P518T%F8QZWNrFV0N2r<=v1M82Qx zr@*F8e@n9+o$(h9+As7@)~bD|p6(2KW2V&l87BQoEzCWbN%f6-5@@mQ1bJ+!RU}ir zUX48~I=yl6QmCo$&u;CzeYEDS!oX)Iz4XFvU7Ah#xE}HD$*KJ>OV@o54}P@AM5t#}Ve*AyxwdoiSkSmY7W^CUi$4=1UMbR8}U!wb7#;z9y8 zx-UZ~%VR?&aD-T@;5ot!hA%YDE&g|cGGYe3a)$2@OolU|AWIZol5v|OZv-R5s&HY7 z!FZY92C(Z>1T+jo=K_F%Sbp8#k#;Kh_`d}q?qk^8DRnkEmKHN^d;*vFA#GRlHj*l0C0V3n-QVf^u$TNH83+ssyx(&- zW06ELWZgZWJ_uYQ90{Jr39)&GiHva5Em2cC&e2c+kV?4gvcFgnXb$OZ5mwc0NO*_H& zj-@HK%RVmWTYPk}H}d(T)dJS5B3)#He2>l4q_yT)%a1LK#^&p}ZYvZ^>tC`gMpCC9#^W4)36lAy_G- zOoH_)fM6>@i=qh{!9U-7@a#6jIB@BAQg8zg?l#*RAsli|gM5I@11 zUJFhY?ZZEd)JNCe67LK4v=qKFIS>(s_8#CfF}Bb$80p1}pw;^6<755uaQx@_1)2}4B94DyMhvd(1;masiAL@rBB>8Q08`FTpaKr(XQ$-(I9L!&`c=xu zuK^$+;cS5t2GhCCT^c7j98KauKk+Kfd~h(SLdb6#e&@aQ1A}b3X;!xryg5A5@L) zoR}{gn$XET^~COA>+y4;)_W%|Od(1Q8H`1isb|quzE7E%c)E#|akwWU9Ys-G`A4}S zwK|2k^a92U3;H7@B$45R)k^NAe%8X4oxYTw^uXIk3X2PYUp-1FF!Pb)!orCmlGarN z6;GHPnA4sVRuJ7Mc1MKpG6MxCLY0H(7bBC+pz+2VT3VJCSUBI4L$dqe!(XDS-E^DPr>njF5f5krFp?ARP)E;mQ(2QSzPGf zH`kRvsUQBHh3g$1qA9uD?wC4MmZf~5V6Bg`JSZu%F2>GcN}m12=1(D5(@@FS)6|ey z;wQQrJcCNkq$|VSK@R$_+m%*uzaLc}7Dvgw&|VMgqF1y>H{tsFEMk3_kU1WdvclDu z5+UxDsXQd^-dGmNer_yYQAGf(1fEgE_@JoNv4~!lQbB}%ER7Yw|A59aB5jzu0W}Ch zC8w3uq!*=LQa87JGV=JZO#slfad2tH95+(t{g{%e&UKQt3-v=@U(v{XOfGk>OSFW1Qtt^ zid1PLeO>Mjf<{=Ppl5_G@+^TJyj2$`j{*Kaq+;ms zF?Q^{+20dR=*a!{q%ou>z-=&K{1J^#sgXwOAM46sZC3n5>&w+&DdY7Tia8M$&YssS zP4OUmdz6b0szSwGEG-=rmin(oF(d7mMd91+-$xtL;5ZLe#O9?4Cl9I@k5y|2e-prVaRd{&iZDXl=Ja8M8j>MC z5JNFRs9m0Q?~=c0T%1Y+H^jRSq;p`%Rjm9TB9eji)be9hW)CSW&JT??&VD(|IpDdW zLd!9g^O*h5u}YVxIX-RlF#Ox{WQ7QVBu#T0wRc__;G#7>?Lyy=B>tpncS8fis`aI?M;Fp zc~E)j!oDv~E3m>XXl@7?`n)0wdfZ49#fFvf^Rya0Cu-Ano3|hEz(<{D`sDV(|4Or> zSKuom0=u9Cc)5WG-&4h2rewdfr{@+6lWN5ul~WP7x#Y7fa);6fxYJ;UFv1cf6DeuTi6u%i zQddAhnLM&W4^+P$?*vQSWSeN&Gm<;!GD&mv;05$gWOE?5;B~YrUm-X;Bw@(?h z%317$J9(Ie)E!vmVQV0fnQzt_Wc=xS&}?U+kJYru_Qd05Mb}eDD+b?EHnU%hy6-%e zJRJKhekCouhpSDT5x9Q1p*1R9wQkX~#eI9CTSu|~MuWgn1F^Wxhg@ap8{VLSADuOKOXVL? zUcmF$-PcU9iE2DSG8YUd*Nr60qxNLSRTI}x%D2ov1a{{Rz59KfZ3`pzfW7%d?pM$5 z=dJS7X78T*V0{Vl^eaLU$A12=C~*DOwKe_+G(y?vOU&kjR7R^P)603#>a-VR-Mc*; zoG~+Rp%49-2L{9%_nry=eKTA0cGP3&#w<28q;p%gKXm1Tn)VT{q#y93Kkh+db&0(# z%c-kLd;^gnTAOWTihgtaRzG$i$afqL`AF0lLcb3_!l?_;u@x*Ggp~Y`{ynNk1JsAX z{GG;J++@j75_gM5c2OR0!!R*L@< z+N`%BeXt7b)&6i2naiH7_V9GFic*19kfey7(U?S4n9#uRK~EOPv)0hZtAFfXx{qO=);TrZRbZSqo-edn5nLG_gy*%IevUCs^gN~Nuq51EfJp27n`NkaY=)(T?(8G= ztaGt-sa0FvY*Er3$X{H9xOyh5F1CnZGqRGPJF18o$5ZhGH4&ce zPN@tU98FI@t;7wcPgA`wzH>2n|mc1%zT6nw3;VJ9BHB4*z`eGh5Qe+M*r5|hwct; zMiphcv%$yx1*h-jtO#cj{h5h0%%w-|o2?xgv}N>@QTT-KN>+IBEPc-2<_VW|Y|0ka zgLC-A-(Bqw`Z-4Vl7Uo}2jf=%Jl}sV%rmR%0eD|XwFcIw2zA`~{Iy*-!g(ZQSIzZ9| zXiCz9Hu7UHv$*qeaRgYZUER6nl3v16HU+}N0h~JLU7}Pq%WsI*ew?MlAeOvuU4@iQ z77NMaY@c%1D?ycem?OA2bGT(V;Pp#-*tS-s&*A zHL8&s>SIxeO>y@2t0Xa?ChS;mH7|zs)N4Hv_cAl28y|oCxHASVMQ2nT;im)g_mNzz zR0_Mi7XUp{A@Z*%(7ATloX4o0(ZS!?^8VQ=9L=zn=eo?^Ppj8r{w7}f9&+VbLY zyYo5aGijfs3iExhMceAUlEwZ%O#OR2laK#D0Pk#OnDgdPbI6&lIfUM-%_)af&N-FM z`A~8whfX$!IiJNynj9i3k|N2NkaNkQqDT&<91;?7ug~v(eD8aY{c-Kuf7fHzbJy$n zdLEcgiW{LHUgvjg88-(D2sN*mFtmQ0u8)ve_0|oT{5!_*Tk4c8@)myg;lq!l_p3!) zLE#xT+n@d{&-*G%9Es4F*_*sRJML(jA&_@uKKc(Ebe58L%tx6G^QqD3R8&Sl6y+6P z=Ky}Z@*t2d0m-BEy#|`vtlrViPrBMu+F43^t7v4i z=v#H+xha$pe>~J`UEfsj#*yuxWXx zo|29?N9;fK(>`uAzGUaJR}YzcF1t6)? zTm^Beu#kfjl7nbZuse(5hQ4`QBb|bXvdYmpV6vRCFs4Rr1dUF1mK>E7gn~aGXSk@t zRO!XxEum$PThf2I>x*l)lWC`tTtq$`F}z-kEG}v0*IW10oj(25XR*`0==btQVa)xB zK+Dzw>!V`}_?-idniu^B?j&xTD+L zv(KjE)Xnl)dMR&}%vG&w1+R=l4&JtjpfsZzUsQ7Rkq)2P26^q3U%!l^Ro`(%j!zt| z9;CZj>b*BFn}d$;?OE#x^!=B()B9GC{~hD`D;z+cHG2LUa3LGC7quhBQem;& zKyYz1lFeOY%|wFJT^$igW_gSjK4v!&A&WJE1m?XGrFDT6%6ek~rtBdtdr|f5bhkT_^@fM)aRdgpD zRvgrHJLdQam{h?b?`b4ys56$rdfPjl1#0Z?T9c#=zdFs-iMrN=WqtFq!4Y*L#VNsZ zFVw+pC9L3Drb~dfa}0!rA9oT~h3*q9`$Mg1NT+R_lZA<&^Aq53!$mnal6jx4wmXZY z!(?q1{(P}e$m%k^>nT=s=rh%^Jb6S#4j?y6j9jrbHITSlWp}#lR#E)$Mu1EYu7%;a zw)MlQYCZbr+l_nOfuCB_QX&W39-d9lei}Njx4E?Te0E?mInU|biVVyJI`c{H;ENnM zhDIpXlvfi|Ab1^?*N`vP=|5|yKcq?s5s>E(kpuLEOL?ZA0fjs>n&(eC1!`@&b^6(n ziY(}gvZ4iKb6-Ay+#Ami8nkGTE)#z+%du&6m?QK>`IC+q7P4Iph&LiZjO%w8Rv30rLv zz1QM*=x_3d`@N0twj_}u4z1|twwRh@#pt2`)SIB*w=bOD7Sny;lsWm=_x;+4y6e*$ zR!2r9Ic|edAIf*%bN_4&KN{{0uKk^i%=FBO;CBEtc#L5k=>$LNSh|xsp*B-q!DvS} z7MmkLIRTvKT@w)|0%%YvY>1%c)wo(Vv(yTaD5tR{#i>GdcRLj^!otr%C#FFren;^V zSTvd&yhqdY1#G);5T@TD7&r@!#wtM3WG%5nMptXN_EM#1?qzbL-O$uay{{v`e2F_b5!)=Gl1r z>F8}f{TUa98Rvpba;LZOgZC|GMjnQ@^cXgWySk`Zsf@I2a zUIW*`Akh98YCXhg&7}y6eJL+#>KH_^#(LIz5oNH&W7tmad?dsRXDIQ@8-a8*fd(%C ze-f~U+r;vNGcnl^1!4&nTQ1C#N>(IWLF{n29y%d*+Qs@X{~;$68GLuD3m?v5- zH$HzjtPs#ReE4lz@Iu_S1I+L8frmBaH$8>#zF(!Oe7dLdu}7(3=TVJ+u{T#t8ImGe z)F6}c>Ok1(^5ritYZhIroFD3{4PU<7S@XS$i)5GYr+w&TbZ%$-(=M$FZho@=-}nIk z7CCgK@hrZ|PWm6G@KV*2#03RE?=82nMQ6AB>5->4qn~d+4{ogvluRCSKtFm~Ke^5V z_|X(I_RH_JeJ^~xMjsoT_$I(?JAy}}i2VkA-U*M}L6|-fnn`E*@7I{|&+(#dV5eRZ zx$6;zO|yPElqf0(L9^OABqf*tAJhC$3qQcl0$u`-*|qA4QUYKUI1>~s3IgGs6KYas) zA*C{}oe0MI_0+Wi!f9S@sUGt~z5HvEbUwfyV=RTQ0-Djoyu?z%!RLJyu~n@nbhH4v z+Yqco$WP24SaIsE$bmCVkqD9y?lA_y2n%5?b-cknhmrAMkPi`YEHRNK{2EUSM|x1H z*Ul>J!}9RL5a1OvMykL9MwK$u-g^OmdSnuAQ9&9k^Ix=?QWbMva5C>;)X={bUk;cE zv@baJu3PhDk9*TKb+8CW)o}Y*!1whidrMtYT}@W!m^SCd8=qGG2pOtN7^;44JaGL* zz~#<+-LqS>gG)cI4a_F&P3K?vz5CSQ+39D=BY+%YP3RX?yTX3Wq^nSCvRVYVv!-vN zwkF1o1PUOre3bJ*JvawaE2PW6!s(tdevWpL*UkO~OI8&*kt-#P!Fr8TriL<2kOv9u zk{-SUVgg6{W&#)Ilwn#FitsNWazR}h&W{dggNu@gm+mR^h!aZgU8zczvE+Qix{$CY zk>m%eM*%q>&ASaxa(kvJm6$r^@>+GM`o{V z^t+WuQU{M=4X{HI+~PAcFo zANXHp9FZq2`8V1;FK5nQP}iKfkv88S_Os{Zi%cUL#q{v&*5SVh2(6Ra%~DLh`zGMr zP{pPG4IlR9yXfgSA48c=RQpltMNKo*losVAvW(8{l4S^Uiaj88IZy7;rh+kSB@tYF zs^)(LoPCFPm{}G%Km#ZVemN_TEfEN|QA8vf&DmkaCxrC?Cv`4+<%f9_$Kg-1Be#J& z^WeO-@;t&clgue_iF7ASh-oek#zIM+Z10`TyzUw&$`B<{eDv&>3JX@Fv^2y^!P2<% zfM%fHK3;jja|#^0f!}d~8~gKz`%t1M7w!!>UoE+8YiGRnCb9hY7k>@{m)CrE_dz`8 za=>lm_hD9#kI(lH4g4>1C}X)s*x4$dhHJmh^oHADAD)%GJ?vH(;#2bE`IddVcT$&L z25@8A18EcS=hO6r_K&Eu&HXcs=>7DqznrMGCmNm)=W2U?)KAaGcle3~n^i6s?OD*K z44A=kNflU2DGQONw68Weo5Ne>PAD7=QbNa^!W}Kw59aob(VP>3=gbF*^yJ|CI2)~C zIo^2_Ge@QL8XB=)7T;HS3>Z2$8Z->KiT1$51yVOqI%~|XJEf>BV|XVw35gX)ZEwVz zQKqUGZxvzqco>T<_k?*d#%mQvH!5!iFg5%hTD4cD#Q-GfzmzA5{?`z(bRT6w1JRXU zr7*ZrFYc3;c6%9y|ByST%Fa@ZDi>H+t>=3-#D%pGswN;tWMX=5ME3Orr@oK=F7KKn z_@?z6VnqG3b4hv4Y~|bgCr%lI#fa7C{?iRyZGk~av1S#}b@?)zb31q2VNui5{jm6pT|3X#<)a{($LT53q`PwposV9tST0N&yDLu0r6WO0V;f$80 zMH=GqZ|Shu<8ggE3LKLG*tk<=2RqlK;~yyG32tKDUd6u83I6kd7l^nRBo%MPL(#;Pj8$l8+%?167vSYo4fOfCLVqmlQePJlPrfA>A*shOeq zs=#T%DHWm1Z>fOcwlRB7WorqTl8@7Vrpc99XNlFFA-w%BEldBb63M9CuKX>3T5lzK z>Q{sEJ-m^6DJwJEq~=_V`d5h#f$P~di%2?O?rEdXPYzkiDc-xUhG#mhZd@uWH*0)n z92&B~^X1&_fYP30cPz#K=C1AEy0RPiX<+}_i``ad+K?F2K0}uI^%c%7ou18pTo{y; zb;BQ3a3n^B7P$|51dXF9^I%bQm0Ig~Q(8WLPK5AFSBoIj7|wP}R8!9K5zSD?gQDLQ zbveZt{?E@kD4zF_x)iz4RdYA*hvPw9sNNP)O7gb`0aZAMWxLQLXzX~oBrTI zjlgwVaNgq0!Pb7j@9CwyYaiVome08~Y`NYVJ(jTO?6MoZduH#&aHAiaag%2b+y3K$`O$gr7)zZqGrXbHA|AooPII z?eX|8Gz#R(J0J&y^Zfo0L^rup{*mHIf)H|CNvPO6g;k9eM%@_9ok3{0b}-g1rUGlD zZD5j)6PD}e4iLZYk4DE{JaT4@w^yez_xa}=4pIBtv=dJ?PcB_$A1O8Pxl83FPtb!J z?$;*?2i#6s9K&?XIyAdTU!FHlTNEEy6w{)Q*0nC)*p%Fx|McU}`e4`Z+dGSUU(&vB zM(6z+A(Kv+YHR9iIXE}~BCr`yTatnI1$k{kww7TDOQeY@mLi+eeGaRe@HM$g6nhG+ z5`#zH`pkD&M~}m+2o5ZSggiC}y#)0snkiF!S$10QVlC-3FRlaXi%*MW$01Z6*IDrH3!;hY9xWy555Sr z(>r**c2!nn;ffI+6(}unUIC#Kc128GYww~dCQwCx78{SJ0dFdq`fnndGRxDyl#cxN zwksEzR_fo1@s+eEqJu@U1T}@?+USb^K%qr&Q^@W(^h5T_N7XIRm9QWwe}eQsN`a_Q z+V-O*(gs(O9OM;T7Ia4Eka)>N*5}p2;{tVV(;Jy`_X4bGiZ@)HzRD?&c|T5+RA{=S z;nizvp)Cphk{97}Js^3}^`VygTE?9}XcSwt9dt@iTHs56qAZzxw(&J+BGokw)^C0W zEkciLBLWoZU|cK>!t^$&lR7-Nr@T6V@;E-K;5KJ+d|25%$;5BE_=nYu1@m zD`{SjpRxPeJ;fWsDr)p(C;X?Q{XGtS>su20z?}H<#O~lgSH!JnBdzZ7i(_leDxDi= zmfYj+jO|K}UAcGcqx2pJP1r7)`#HFEJ9@Q+)_v#E6qN|bFfCxRZ>OP!-n{;~DZE(z z6z8O`=FHa!0-Y(x#6SyT$H7=wOjEG|zX$UJZ~6_KbxAd;0F+defsW4;?TfV6=Oq{Y z#CO?yi0(4RwY4=9_5EsikFneQr7tdZo`cVB>L{_AqV zCWuOUed`VDf$NE>F-G*`O?9aajBSlFJjo-z!nCih|7>ECp@sI-$1OjzLav0rJUTVF zd+qf6V1wRGuIXuuaBBwR|NMgMr2x~yte&Iumf2F(yEp#bnht;rC;{+dKhe#z;MF3< z9VOV3O|{Bl#f18JbHXZp8c+j`0D&b?70k{g8T4Jp081NQBWRm)oA&Eky0Y9GI7-EgXX(j=^-TO4(~( zoPv7Kk$y2Db-&ZMx}V5@4R^}|18*|z6ePmfwhvBq4JjtRji=T`muOnL*rJ^TEW!`J z8INL`#i;yzu`01FR(;ZD@dT&ECHr3WX@iPO`FWG;sapaYyg$gxhdW-3@9oJCzwg$Q zG=3O1`qwYohL#I{Mel*O-FaeSkc2Uy({$ulGipS>CI;cAvJO^2DbP;A%z#cPlCJ_z z0V{%6Wapp&3cqXZ!dba_w~EwoDZ3Ytu* zWD_CbpDM*3M>#h6m)#4O|9vAr_V3-09=rR`AlLE?R(|baRdpq^`BEixp_|Hl%(_oU zt~bW9ANV*&OZtVRCJuW31BJhWzt`Qkr4Ls^1QwaK+|mcBG%M+U9!ZAE|0sngjz`pR zTA!!pD*;^*-4v&$4%}C>8$nf7pMN)GNa&As^?GhS-5cxI=K7S+|Jc~Rd}}uclIaLA zG({3;6$$4hwWT`YItSECWk1IO+qhNAG(im!i@*c}^3Yfuq|=H=&4?G-haf3NU@bKL z+N|x79;8Z8Ssz(Z5Xi&{4V8i5JbE@eqG({jzMU=tiRYoq;q`;bczrau`r-jHiR6%; zwwQQP;LL#wC(EKQf6fR{-vt%TWzJZ#FYYJJQf_b#JKYq|4;V{g=rcpp#PdFMNnLxB zpJFyKjPbg-ky3x7`1jM17I#;v(IXVB^=HyZ-HG40PCc^gJB@35=k^q%w<`X=?-TBc zYTcV0rNjsz1Ysw`DCG>mYS%;Yq)$d1)BCC`Lay`;#a7IWG;NDjs}QCX`6XIp#DYuZ zHN{gy!}P`hPVAbSNO9aW!0JOCh|I1r7pV2wr&|!2r=ZI9`s_oCfsQMO5S)-^AT4~n zak3&Lb|KhIq}sD!xj(G0}r8Q8iMbye`~6ecTzw62D_egx3Kt&2SKCq z`>x&dYQ1;gvd9NoepIgS+x?;btgr!g#10njr+iMXom!2rEjQ7|cAO z3uPxp83vpM!jPG^goB6~$dm!_2BwW*8v$;}841=oVWk3d0m{%Sonj=*%KGwJHdcuL zcnsIZg3~bbY3IhME6XX$G5r)h+L$YD5QMUja02;>fYq8{j1(>nCYWihiQTskk{n}O zF8ij@3BOEwllKAwQ;79HH2m!;u@aBwrTCZK0j@F-S*>AfkFArwrGJ;l709Hd{@80e zb~z^eqt4I8XLYs>@ZUb5>(#TaQ5RH_)pQ(w?ie`VaV#hslnN*GM7#Z6G_0!@w6oiA zusgQ1I_kD0{b{^@V0w>XuvRp89z- zBo0##fVALBc4vU^z$!dPMP3C1c}FA4LqQZ6(oCQ&k*WY<@N(z1NMyx1Kd-?OC?~5E z)8RAxN7{nVTjaiKiz_2U`W z`{<(&iiSNB6vn(R=7rrYtDvcDYL-7JUR})1ukS^@HuxTNrgL8Jl%RQ(*h81whFhW6 zyRM`kd;g~AOj&=Ds43hKw}T1k_sx#>Bo24m169YY7;w+b)?5>Az{3+ zW@ak?G3_mV)^M31MLkbSBpE$2=3`Yzhz#up&{;e=b5>)81iq(;BDu6>Swc3j_3uuT^j@PpQRn>S!xCpiu zsP#{z7{PQWinhFFwc=~^-4Gb4Fu2p}Xg5|lSlSO3FJ5k&%=_a**0c+fvK*)v>-Ocr zHIJ`(hQglTC--2;k;U|8m92!p4-KvJ9>Y;~^3USCt37s{#Gpi*d$ZP-zg#z^o~gZ_ z%`@Qs%(%fDf6UA_H`nIeCXcpC-`DJRyxhKVEOk?BY%`ks?f<xXX>DB+Y`GRE&7yVYWo_4(B3eGHWRVF1GGxc z&Z$0;7=WW}3zk>)wXU?cJaI%@&HVkt9L7F6yKag$rPEfj^72&zghbl9nKY+ujYT6U zHvaK#CBeun>4BQn*DD?iZPXmNEvY|@8-+ovow|9-qT#tq%&QoZ85Hbe2v8d z{zR^8?W*c4u@TY8FWPS^Pe)(-8@+jOZ*NEAjop0l1LqxJcjtv44Xiw<{KYZn^8BSw z|92Jtcfeh@?QQ+vshRW!+rPS}L&!=8({v+FW5ak|vUYaik4RzkYlgTy8Kyvq z6&2Lc;s_BG9iO1_5?&k{!@`7zK=fM?!9hTktIduOXqWHu&|uvoxs?wt7XKYusCd7w zU{zIC@wnkjzE;)27eCx;inF7(v+t3sUFMg58Sspbsgz4D8F-UmkH5J^q;t9dQyxdu zI#Uk*c{d#x`R2uTPyWHb5$o03&e1c2^LmWxjkM&5el25=rSTQ%dY<87bw!b*y>|N@ z!fe57A}~9652%)=3};#%EXYJL%TU?i3N^a?KTt^EhOyaOCPWZH<2^}~r3H{Q+)hzo zS&eg1)vN7CeM^*pbs_ZPQl^$Wf zda32GV?l+v#YsgRj69&(tLPKrEd91T`jp|SdZ~$3Y))s@t@9)4wKa<;pR2zq)>D0I z<>;Dzu*@)fNUVCj=7MzXlFQQz$2w1eW^VtjPL-+rG^!u=b6GKn^k~Arbu<6J`zKr) zCO2ERcl=(ce45|eJNEMi`PRDLmlt<;4nHIx(Kt07k=}2cN+pqxT|i$)k$3p|pkjTO zwE9d$Q+W|-#LAzYDc5EH18hn=r2vn5ai}Fn>!ggb<~UZm&toJ$3}+K;c)m>W-R0~?_|D?r>Qd$v@Px`lgpKnXqgZgv4~)h5d%JX0$ux(F+A0!G$kU(0fI}W zry9ZWSgf*epeA1X&7%P*di?M^-`TuVBIPpTyiPuccT)>=+Cha5nJ{qp`@(~Vl-fS% zD5P;xHFHWaE01Yvv|c0B!DR0@Xi~z^CuJeIef#Z9PS_nfMC>b2#mmb{((Cs*C%Y*5iay zO;i9IVjryziR_b`k%0H9A}lb%ZxbtOh_6G+NkjS|1QH~Oq#0S8Tep#hVK8)fgQ9H1 zsOX?M1O4)T4+}5kEb?}W&0@EyuO-*9w2@Z`Tb@rLB^~GDd0zI=&#mrJMuQtyM>=cZ zy!mcf0lwee$UG$E{RshpVE(W9`I*;FxrWECOo}1P2*po(8gmj zU{y4VC^OWaYORuvs1Vj;Hu`!0Y>NZ=oOZxUD|pILZ*!1>;({=AQVN_UCcy-Oe(Qii ze$w(ti0Y-9gfL4iIf$=u=i!hahUs^xnSmR6aRh(&C z@{X)V2RthJRCl7M)w89#ku%vs)ov{Rap6{?@kYp;OY`=~`JU)&%hSaM*Y(-@Ym&Ei zqMN&xpCso>?7pZ6L9C6tFHgio4zGk77Y1x7`p-dp&5b-4I=s()p|X1@jg}q)S;Zy@ ze+z7+qbG@wf3g!}FDd$&r6^#+WCfYS_FdLAQ=YMuv2YOds;4+{9`+U2}? zc}e$v1ffgrfU}w_?nLwD3lY7myI2gwB0lo4ltFq`?9@6|suWznUcf1f*4AzdfMnw- z=i`v$NHbC)ah7TD#8bf!8|-}t6X)o4U@IL=WROxj%#i#{CYtig|B7Q&IOv3ECaIRh z4fl^QmrZQe7z6ZZQ_4(jEd z`J`(n^J&Ro*-(pfrs@4r$C9PipF8J&JZ;b!3C#qKfjGhhcU>OJT9}Ko{x$~cmY1kM zXw6X$W&_@mIXpU9z>vr=nq)}Gd8A9U(yqEBl&okd#`p~CRE$xQOfr26F!uv}C?GK$ zpn-t5pwz3LW*=JtNM;VIR8D%vq8)S^!j%_VAT1D)P%|5trZ6cG>-eZ2%@DIAPN#ML9-;@~zc~9|P@}EHH zfUnUy!o%bW!<b& zms?n(jd4)m_Ln)TaCG4z0#lSDAP+0-jHeJ)GEXx!;n*Qn4?Hlm&}L+3f4fgdfG_5D zKCu(J27|uK#?fh2F%Ze$fLF}vzvM6X_DS<%G|oRMOEjbqPuf!)lT-9-!nbnR)}r*B zWKfU#lWgn{f4CxlI6M#o`>SrL2Ij23Z>ZGho=84NebDhyEl;h_@m%2U1^)4YmL=D+ z0fTr~oxkmY%+ueaeqR0G_>l2C#oqK^yR7K9N){Is_VwFfxtu}=^8d*cwj3RN2B$Cg zzq@wSDReoCA=!NP%cNfIv{t?9(Yc!fQugk0@tg1dkiqm0jpwxpCb*DRWe6RtyP&Gr>*Zr}7OY!2r{sKSh%}leDvZ z6D2`FBNDi#5&CKzhr+wae!YPUb&HG4E|O1!Y(Rt`pUg&fah)E|__hyU(ou9N6%*zB zoqPmS7Q{)9T*=mSV_p8(U+HFEeDhzV#$9pK$RzvdJ^nJl-M+>D$ z(*h_*Voy?R!3fG}Fp44zVu*os*f~(j%Y>5?I|fC4?qrOPFkT_p%Z8i=7zqrhwCp>c z{K~EmZCJv@>X-zn`*|c(oRpMyWA*-SQ64D%nn(fryIxX7Gvk~zgzp`p?ftZm-E_G<8q1pR(%;OWWV zYZ!btATFl8e`f1gocOTqECpz}5GItfPB4J3fr)wqUb$fus05G&lj#2eJm6u_5FI!P z8s?eexZEM#{qoD3suU_(E1mu8oZuVyDeU~G!awWh_o99sTJ%H*92i(GIPXvuHd^~p@_Tsa_lRh2qQGKv z{p}C`Kw*K#^Toas9!&v#LotW`aSBT~N!${R|BkU|>=8Ej{>SLeYuoR+)fKx-?#+Rz z>z2`b4@yNW%nZ*t+o3eX^{-+*)xyDPpV|SBj*|^ID2%ra{Sao_Z(41Uqc|uw))wjR7_snFKQvV;~$d z6;06O$~NjyTP=}I1of_v+X&Wd;9?tK-$lZ7)~?Y0!@#pcL4dx|6)bnN6krn1#!QJO z9ss_$5GuV1S3!Jq^u5y(SsVH4BpNr}>%7!vi0dmNc>2b9FNRce0)6*^_L-`us9mc*(zADLb0AvlZ^RZ?6&Y4Ae>+;xS7?-E zES)hKv)gd!bjZWKo&TF{|KGv<|3y6P{rr0!yEG^n)<}I+lrY<+NtswpNV0rG>A!CF z%6rB4fgM8#e3dGG453W7^dw98Sjm3IC^3Xej(PxiMF{Z=rC14pXE}M_D5&B!lQ|=$ zj6G)@!v3Ksqn06)YN*H6&*(dOQf->d&F;gQHToD&f{@HJ2G}gq%uhr-wTctb+%kLMfB-x7O>z3ktHcN={B+;)cQW{B@55h}WBEj4jX;urF3{uyPj4Xe?3^PH8;V`@^R+IQ>kn?vvtC ztcQnNsI;khjOal{{zq>QJW1A32j_X`$u#}fTD?%Yw*|ei(@Q)W4D$n#r4Oom_z6^`|ukF(pAsG0F$w z#76c6FBwORWA}m4aN@`YpvSHJmSqmLfyYx}<5j6|kzI@)KC<7$i=;lP(j7b!Ng<26 zWq^EUK+?LjHX;>ixUCnU;wT-YgL*rGR2F5Rz&rwJg5TW#-ddEu9U z{(@_w71tTh>m{wof4Az2bqSGW8xh5qD?iu;OzzH&KNz0aOeg*s2#bEW_}BM#e&3=B zbNQG}(Uk;3!!3>F<)tUr_Qpoam(I+8YnAU?kpBkoLuXJ!AwY&A)L!TSkdGL~QELGM zuGVTwNrqeCM|%NCfa*cP@(B7rL1TQzCdj&n=L!Y%&a!~Ad=4Znru{#iLX@fk_{Vgl zEMS4%PvgdJ^a&G*L=ZK24QUxTXCbW~#EX`cype&%A|X2YuTOq5Ne*DBs#0m4E+zeEY53C z(Xmy<;a!kHcv*R0#or6-s`ZT?rfE=W(ciT#mAJLN^_=_LJHVHSy*+1=eWZ8(?n3k4 z?*UHh-rm|7E{FFdS}5$8X zD809;RWdC?H z2!29S!6H~ya9hj*hG`06PYGfJOAa@!YSL27@0=*2bR;L@_V)KdgPo_p9R9Zs zbpSBX93kSUs@T`3q%GX6h)pu~I`bfZRGNM$R)jtstB*!O%~!4$cC)E%LYZTDmh63~ z;<3XB5i*Jhiy>zn&?4q?A@D0WspoF97c;i`>UPF9YtSP*5=A07OsZBHnl)Wyq;K<`-m|$`N zR?cfBDwF36%epesT1Oq_*vUY{jQrR{UNGG#P1z5XWF@p1eeTzH=y1TKeFaEfo|gB( z#a6^fUAwC=^528P3vNK8g*kNM^2#W0;tDrSL2_N`-$t_cx?(AK=}6SFb@}HrNuS%! zWiVBbn8j6ZOs-X5ZU1gPCKQpnmmo8v|2JRq#?HsR#ZR2kz1`c<(+_GfBPVadqq$N& zeRHh1JT*fKw7*%=Io94C2a}*@taKN6A%tQnc;=Cm?#hEqR2=EiS%#Z>O|Xe)E3c z^`z0cRK9j=jtZI|m+7}f_(k>|Z|tlr=-UtW>JSwp^MSA&;_*~*<8$q7(SBn#!1~_r z-&PWmPBJrsFe5=1GX1ki2!}8%T3`Ag8XU{xa}>-p0eQ0h(_vFAUO<%j3nNANywD++ zqZ?zJ+C5F1PIi-jUx)Qld|x7LU;E{fg$RVsy(bir4P9}c4?$agPG37Ooq>Mzc;l)? zvi8nqTxsZgqoLOap7CA1Ogv-cd;Oj3k3egGcMUx;hMR@tZs9g1>BQ&$gLotcJ`|7e@tmGHQv@9&vY5LYJynW*Tx9s8q5a(WzH%nc)@v&qeR%z~X z4sUvAS-5|Icj&&JXf^#a874Um;JKJf}loMk(i~wpK%sr_w%A9a(XC!@A=@lrTq(xJWP; zuNNa61s({`2vEwj-ec|5^ZOkwv@BMFZ3CcfnH>x#prBSfd}UP!%Q2>fd9}0Uk@(bf z2{A}4$?T$-EUD~er?L`rqKsdnK;`U9+y^O*?l>I^=(~RLfpWr7Hy&jVW?npraj?Hn zsH?X_f!bL-?|!9gI4;TYGXcdSYUNqY;|1>%1e)AVtYYJI;B6-Hvsqb+>^C*~9%l{p zLhvt3`^R_esz26MONeb>{p~0F@SxMv?f>P}2cE$E4=+%mS0e|hh#h-q(s zdEu9flS8a0H>H1Jn=%Zt3k{jiB`s#7{uHjhj(YmKo!MDz!@x!{O}SPP|h$t^r*mn1r8eXrVNBW?r_v@vfqdrWJskaCbGV+KzIN=4-4vhH)kWj(D$bm_}iUjmOg$dN^yf>EbR1WZ_dm14GawF$`G==3vVNl@$oCz{sXTTH$QH<30 znuV`uTB5V0p|L1r6446e$uS>7iePwZ7YOSgx-Ldisr!Ae-E87xQE<^MpfP!g>)uk5J9OnkIM8r#?3n6@C1)x_y8PqiAIHGhHshFC(40)5kLLCF-d)N{)9; z>uzti0}AM!0P89nGK`NmLe81uwN_?ULQ2MMXCxqf;!vbH6NGYr>t+H@`uNy@x&p0L zDrE7b7|WUul}Hu^`;lcySx7eN602`|v=!^JEOHaAn`HFsq9bqob1Obo-@%(DuBczY ze;d2Hz1gV9ons_^&cp8(&F?cU?@H^}{Fn07@iF5vcH+dJ_OPRaKP985MIZjU?ygwM zsQ6}n&`P=fqv+$yOAdtjh@H{s{%h$+M*_wN9K!Fu?|i8Hs(DO%(D31Wjk-=d<=|Gx zcOCW7BPMqWPe9qpB*+C#A_6$+$B{GBd6g#i*2w2;;#I|WwA`?ytZwP5*hb-Z^g|Gp z%zdb+7#cr4SyPf8i-dz?a|M#<6FgMfd;YKVkFY439RF)T-{*#Ckp;txRn^cl9|*#^ zReH*0#UK!#AROMz>ws+107K>g_Bq8wOsfePq=+c;z~X#R@&$2A($bpB|3G00gc|UE ziHN3wJ#2onxCxCKhe>9*J{mmRTm@>t0y()+pCCh}QOe>xp!ibG>J%t5xSgI!Jel?D z>>NJ`!5dFQ@#*|ws$&r#t4B!^er)jDD#kL$GDt_#EA6>iVSHa|ORaQFA?)T2&RWJp zaiOJaGxj=lzqQf|uHSaK`s|0n1*^TZs--^ng8ZY!8w1pRtn6ubWN5%%?-uM8p~t4k z@kftFPu;-f$v=T%k5GS`U7I<32X~_P3@_zvZto4Y?!~_dn%q%$=kR}MP1uWmwi|tH zlRGnV=Zd|(CGJr9>EFTsUW3~V+Iod!wiq>`vPwDg~ohtYO)ex9(RG_TtSzmZD%-WMen%vtb% z*oUV%IyxrSnvodTScSvu^W%jD`OKzDNGy{Y)4h=HblJy_&rMp2yR#{%<3=iVsd*GU zVib9GKw#PNPeOD5KHjM7!_-ias-Xli!3*R)QP9E>9WM!zhz~0@mA9P{AYNdB)8^Itt8*_?4c&= zJnQ?)sDMFwtzATa)Eqo_`bR2IcXp!HaI5G*udmRhgURZbD2~XPd8r z=4Neul@Wa;7V5F@p_OV;%|r0#YrdghA5zy_8T{)Nz&r@vVXP$=>Acn#${;aZ`e*ndhw+sj2uc!_sF#6T=;LwGMW zPfXgAXu5VYpR?rz(4<%VE*|nt9N&11K(6Y?q3rG3?6M{m-jfn7(RT-Q(ssg z7Z`fmQDtp#-?Zn-)1r{e+6NYPt=>ugzv`U!IHF-M@I`#Pt0R52t3mZ9A1FCQ3o%-OdCznnwWGt|0mH>+3RBVy=#F-CqFv%-Xm~``yzoxys%{Wv=0u>1Yy)MVImq< zxr92n5qwQjOnu++ujl#ee!5u>AINg*o@g#CIHsMK% zj-M1O|37SfQqwKcz49$v)56EPC(?Exs-q{xo z5VIB0MSd`p@?3h=uQtB>&mYGrc=z7lQ`V?&or`8a+kbdl-daUNicW6HvuM)mhHLx1 zE#&cx_&l?R)-h7o_Bt87bk&lJ)NM0f&vY9$o~7g~7FGN@=V4yr2&GGCR5ckey$Kj@ z{x+0US}1&#mQW8>O13VS*1Y3HN*XU=a(s2wP)6z|xy=k}R9-wK>1qX-E$71F9P42dvV zxu|GHx#+CHH`Ada+rgnpRd^9+brshAQK-3%D#P!!-7z%_OJQ))5eMw)B0){zI%~=} zg{$ejNT0k5KMZN!lL;-C`J($+X`03uTaftc&showac>rzJ6l8|#)>Mula9!>& z#SPT&&cdapRNv54~@wB z!l$!O*)d8Wc7${JGWjY2DtB!^lXvcAuU4U}#k~TLmuV=iIfIMFBSqDVX&^AIKItEo zqd3BnNEwR(0%F%}WFX&nmvMGiw*~Bd4IfbvT>Ro>g0S;Ya)ONaYbO9+rs(U=hQ?Qo_e$ zS$Eaokwmb3Bq#*HTV`;<(V%jVC)X2HX}L`nK2qr{c=k- z80~13q#AA8*u>xud9e13Rx`41E< z;-3cN)qiz4;vpdAh=?kln3^?%V z01|Q0inT;EwR9K-^U#3Y6$Gf5u1MFGRCJz{_OwGMyR?2{>v4_EKJHHGwv{43Jc zWK27k^1|EjlE&4vKb(nInz&6%VyFVmFUxGWijuYJlVcQxXuN1%7f*=A4Al~i2DK2X zn&E_W062OE=_{Whb||si#UGKEbg{Bew)^iZ9!85qE#L=D%-1*;zc6q(x?xcL-ksu0 zx9DrE;a-wDff0h-pD z^FkCDe#TP^v;VQ%^fb#OT(ZR0rRj z$ezmcq%`rORU`;nt)K@fbVklgSl1l}>liB}5LZ(r5n&_4`yr5$LqrkEgCTmuN0TDU zrjdVn*7Fhm{$=m%O&V@mo;?!2!Ou5u12=5wY)?JHUi091lFjfFi*nOFH+fG})AbK0 zN3vp?Oq8OT!W5cG!H{fDPg#ch&Y1Sv)}ilTt3OX)hyHrJZ--GArUiN5dnuovuTR_S zfKmGd0ImQR8_t`_3G~+RJvAeYM*_^y zGOk!N?yUZj(<go)nYPi^GV^T%h$!d z)XMQoGn>MiOcPR0|vxF_`Pv`1hPf87ZtlIO}8{V9`{_$7v@LaTbIp7VB+ys(l zf4E03x|vBqQIx5G_$!OOc`4k8xq*eOK!sVEHWa0O@V#NbE(v8 z+SKk`zFKe;?0knRms?+{fJEBr$zt#WL%o|_Gl+d>lls1Dv1aC*uG_L3dPbp0ijP6& z5XdZJ1vgyDNW)Piy?l%MoX-TOt7#Q$oU9_&L8R!uJ(tbGpawODX_I2XY+FKKP1OPYyt|f}u=_>tCZl2`8(Rf=i zzD72%X%I*lf|#;BX&1gAxJ)!z8$TgA#9=p2l9S;f;xP%6y@`k`D)>+#l`8FGY$N!*KxLFVdgI7sjx4y^`)z+R*MJ(u=Z$Iefst4UPqC_GzO}7BB)H7 zrqd1~Qz1PaQ!Qa0q3@SOS$FOj2lEtvL@(7lQ54uTDc>?h4tJ zF&ik=Ha%&JWlyNdn9fwwgy6tu*uBNs6Q0(Zzc<3O#-6?{G^J3`&8(YweysBYT<3kU z$=NM7kJ9>R;Q_Gb0NlMz{uSS^bGQD#Z-dY5*Z12$9FOgu$&xPH-$yMel(C^GKv<1~ zk-!fsdX*4~|UPLiZjJcU_$JQ|ly=+HJ%Hf`g}b%xIV7*C`T zLC)`TaHSGH6~bN>NWjsNj*^-Z%>~#3l-s>hJ7QO~U zt@&JfOlmgI6TSKy#yfFmzG;*$mf>1jF&7X7bJiJwVhBf1%U*|j-O&gPFaa_6;Dyou zK;a_(8Q2U4?&RzIcWTnv;o8yoLPQa<=g%;<)cHTAFb{gLiln3;hxs36cxkx<9geF( z7z~Jk5TBP01|KHt-)F-CF^u-ml*|a4Rf(s#sEmiWxiV8FMM@c~jQOlrAV8b$B4mVa zAW=cORd5!HZ{Wbls4l%53M${_3vP#%D;igs7jGpVO9X2~^&uk@Qwd2asdSN6`*oJw zJmO9E0BP^~B(|wfR+Ed<#Ftr~CfA03fSd|neA6$NUHT3dXap+c$@7bE(I8d_*8{Xc zM{s3H_N|tvu``mGG2XPw4p#;&0SB-3)d!Mw5BA`KLRY0_5`nA1@$0!db+*mvx$eiI zVa5vMms6I{>ceaA;YHW7-zHSgGnHUV?rISxk?eviVPuZr?-n~T5#LL*tUOydDwFgF-&~;c_o{K#0zUCkZKNwFwy=A(t zb1~KZ81_9m#J=?J=L2_2b#*<#B^<)EhoyZ|WZ3ZGQ_0eW?JZ|%BouY^jqxf2-?c~c z2H^D5@9*;0p7#69y^`+VUmfo&*Ig&lm;kR)j;ia`m9?_9*`_a!udfy$5ivSESzrC| z(_n=MYALFT%-^We^bZ7vWWcb(U`B%3-tzCIl2xe+^5?Qav+1#V>!)i_(^VDx?TFZ1 zZr5*TMlBKu#OptCkt)Wvp&(gyP(h-U!)tb}h#$i`EcS6!Cm>A!#R~~ZO)afO6mmz4 zQ_jQGEDLSgfs^Q34e3fwc^C}d1oA^nE_|hc#XOB4-RD%2UWMq-RJjdagLm=TNEO~z zd&3xmcC0>5W2iO0Xa(P_No$s5El@+JYcgvU;D}*x zNk1sPV>4-7-~Q5r$to8bV!F_Y8TrrV1FB&#cZPL#+zm}4qPdTdNY-#l_d*J=EHA2f zRdE?<6NeZHq)?k5%xf@V&9DB_;&J)%EEAzH>$Lh@m=)TsdeSN(deIn~5W*g`*ivH2 zc8xQ1Nw&PGF;~Y3@YHF@x6`>{wVK__AxFK9xdO+Z`2R7MGdNwyrNn&UmLb4mQ5fcRfARs;sb;DVIv=M0HW8%xhb8s%5;nfYR2e(|E8Nq?v_Ah3KK9aNf#E>fWu z@?gU55K0g8PvBcL=SV64qP@>J$2KLfAqZYZ4vcc8iPzwbP!m7r%7J%7vk|T=8nJPW zP|da88KkhhSm+L53cq#XUtw7(4Ls7;qEQFaKNl=BpjJEc?oO1h!a$>o6oKG|Uxeiy z%qO>4Krc~SF)SL2>d$p_C>m?4mf0{Ej+Q;HLnWr)z*ZtKrqaxBs#q`T&-NM3!Mh}S z^ES{;f9^Tnep#!VTm4?`A7jSe<8UChx4N(O{qEpvWu>>p`e)yzi(6gI=jX>E=fA&* z!%x6xP3Ia5=nCh}P$nYVqDPvgxd_OlYCGu2@iPQcP}r8VM=cBOLY8xgB)+ zT3TYBB96+3)I$DJ^Xx z{5UeLR5lyyNJ9q{eR~`ien+X%DIL6xn=mAwMl()y{z7LhJQ6~`(Lc-JMG229{PStQ zA$g^;wSG+^VO|Yy8G~4zVV*^BOR>DDro4VHtLeotQ&Yb28V!y&`g^l|ueR+nFUHTx z@Ui9}D4ZZa5BviKU+4FQw|`85I88(q$P|X+8*D*=pg`*s{jRo4ImpVOkw&fj2M+kHq&G7MYcBN^9j##`w+7wdfzzK`*-6{{LdD-+vm(l=JpCnM zp7gp#@>S9$N@|%%x>nLvM&i0!~V@HvP8eyqvlCFg>@(UmD!7 z7rzzz^vwQ=WV^LDTq)b_>jgZ$C%<&=aOhs1P8nF?SIhL?#sX@r0Qa|F4PQ-Nm)BdT zZ%&_wKMAb0eQrZL-3azMk0^BH9?DrjZ`win16c@uYoloM;>Pz?-k$xGPh=eXfOa|% z&?Kl>mM2e_a>a#7OGs`Bl#Z9@E;S~geb7xA=98&(*f_Jxh{uMpgBO|YBLJ8c#jsD6 zc9~qH6&JE_f3wmXr(GIxXdzo5b&}#PGixh>FHrCAV6RTgl`XIgb)kvFkngi5~3Q0eQn8s1S}>Yr)q==rUknRrG=|2w4{mfxCIXe8I; zBQaPyKhh4$(ts{U?xQS~ngyPAT-%L5kRSoBzm_|_=s0J8x5yMC@Q-#g5%8OWN`g_v z%*+qL1w*7@R*Pf)4xv|-$INA~4T@1H0QZJ<)J0(n^&HRc8a&ZcT2~asC-p#gU(s8T zNjW5qaif7m_f;+?a4c->X3y9iD=;rH{uVY-IfL`buL>uo(1K!=NT;@A$RI}1h5c~O zEtaCp2U$RPbWFtxe<4WLF0!c=`}D$;WB~hZDupGcQ#@ja++KbT4{Gy|Hen@vhv_1_ zS4T7jZH^7@(N<$rNQ(5LpfF85kzuWa<|y4wF}ZRhOE`mb~IXzPhxKbMk--c3WjzV=jv$hZvi z8%_kcG64}Dl%mHgtp?3P(6ljgmjEIIL2RKk@U%KGe#bt;&V$T16sUPyGwl;xI!33> zDN-4WJ1AF1x;$;&mS;xc%(Na4b-0u8De73nmslApa%ZTwVo7o?3J(hJ>_ayTJ>ES3 zC7=k!evltP9L95}j}yy*``}cT@`nz>EB;C;Ff0?8zg##&^K&i7RZE{n6mvEWCJchN zr(w_?YgZk?kHlPBdq|D_uwT`&k)4nqjf_1%{=pIb0eH@FY=7P9 zPW{)=_<;Pvod8TU`nte2!WjcWfoK!R6o8;GJx&W`3hg`eJzC5qB{kIt8(DkTp0jP2 zw}9Q2%btI8z+=E{R{ZBTU8^Ns=ZUsbLhtzr6dYK}kwCCO8dDMoxe?U>LO|HYWJ~JM zFNsu13szRMfeAi4F*e%%>*46(0 zUs9b>r$~IM1b8d*^w4_6(Q2%jFa~^u)qU85i6n~^ya*QRI8sUOd)zC`T67waGH(n4 z=;Jf7)pld1L2w>5Jy{Pmr^5_>-NSH}cKthTdZWuUJmG1jEskV8v36$8zos6qWiC4} zFLhVgsx1j0?d(1eeRsINo-4KXJWGXEyH}AP$cQ^aof^6JU&oilpNcRnKRJABvo>#wGvlR3B!B*)&0W z{9e+Cux_}4LsTGsuA7?cN=}iVofT`DT`CbiKD3a~Q0`tQl@sAo0y~nLN{$#M4rT!- zTY~b`T**BuN3XXyQ-(S`AURB%Nn;p$D#a!n(%aC|UZ_kRsEuJoOK0zBJedp3g}r@v z=$+0pJ!Z`}WG{47oU~xI#%8T@ny>86oTjnku-xKrJir@m5v{b;JVvcu60f$rtj+EI zaRTgA)c9>K*FCI__KgVAe{$r-$JhxS08Rm4LSukKATv;3^?2473+yCG$qtA?gw7Zj z2crcEu@*PDQLb<4N2yABmNJHqatjhEl+sdJ@chDy$v1b3i7?pLFZotKKO#${w*prd zPP8PuUT0Edso6>|hfiw4b>yZfVX4l|r=7+7BV$@@;quRnESjP^IqL9P2Mb@E5H-~# zcUZ+}XxfM?=`XNEEiso^`ORRIg$pbR-9k^k66EC+Ni7cq&Xw)ZS2-PW?DcZQKRUcw9ll=!?(4q3Hy>A(h)TEPuV579ILn)$(JUAf;6W3v zA8=JHg&CYUf%7xNl_S_u+`J~8B(rB|lua~H`Fv>MLdHDM?o(-81pN-Cyhoow@mL(> zU>J6z$3;a+K$;bMgjelW{#F$eQ6&#MqGq#9JkdrGWkMk&w;<>g^drf-R;q&{%!Akl zY?DE>R{?!&z)U5hkq{2dlIvGGC%U~4y4k>18wDkAf|C?ax25;@WR{Mm#rmV9JMqx6 zhpAUur1YjzA5|^BF&C%m^{&4Y0(Nrz)zaT;?oYzAc8<7p@-T+sHz|PMWQ+QnUe-(d z;~!D@8~=O*#DsWX7cf>hV;3MM-2InQ7+M}X4+LVuY99CdYOl+)pPB#GyPD9U(53&! zC-4bb1AHtI5%0y*KkeW@CiX67@X&_hXOJ+%FmqG%fQHn%1Vk3SGYqm1JGK?bE2AQe zzbK+{kSL}i!l0`|f$cWt_-&MIrY0UFoH5;&J5|?@{VX@77<-R=sWi1P_v}jJAQe(& zAuaQj*jS^77In$!9gDG)lEIcRpuNebGJ`tZTV@MxXaH6kPC1)HS7b9eX8vNtr-3DVoxVB$?L?OB8hN6 z;ycD235h1MBLX9WBgA4s24TeiG!@K;ISv?0zmlVeS+Jti^JCC);?%neAxLCU-w_-b zDz!_QrtD~zPfa$2EV7djN+yLWZxN;z6y!?b%J2jX4yDrbC7T`yWTZem+*wVQz=*=y zCThCoE6{{Dm4HSW<&wdIwpT{POY)G09H8yDzcc=+1P$VdV3wBAm3T{7RiGhgL0FRO zn_5>YP1~)vsWj6p?Kv)G>6Br>7hOH^zVz>wzPqup=QiUmdw*DYG#KiA?)mf`>SdI- z?G^BdIoOyL0&oI^eD)pyM*hGI+a3V$uaFU+_w~~Q*=x6a2#s?CJX#kD14mmV5FP|{ zJft6F6o;tSWPhKs1EDFDr3B<5WVq0$P$+ZhvcNOdgbw#g$Ifqf)veYiTXy9v@>r{4Dpl*LwU* zp6@H)t*+nxW&#Zsnr@@bh*ugLehF<>nsn!GOz#uwxx|qR_NxqWP&(Sts#YhVLZjw4 zy1sCdOb#*F2FHMUN>_a2U*OW!azvX`KNm@&Jdt|B`dA#_u_lV04BNtIaYSZkz8$(U zG)p6Ql`0fK+(#C!pZF0Wo7>98@vTZaM9uZ!G?9s*Y_h&J{vnI`%$`*84&*PlVcNn6 zf6`ox#Ri@<4pn2ulNE0iSWYsOu^aYK_bDIZ5jtALZ@)RPEz?*``D6W6Y2`Y&rN-T9 zwUfER`krD2OZLZTBe{WCvWK?7uphlY;&b$Nw|0IybQ$5L^R5)_c|tEoou%yZ$)Y1^BMIDdolY0p|9A zDiwKv*A^!wtn>9z{LmZ}LsQT|mpP+!g~2yqNi>IO%NRg|UrZRI9Hn+G@e z#7rTv^;nkiVpW1@tHd8#-D0MqvfShCmTK*7)N{k4xg;B{-?7>%9z|6$|E9~=llH4h z3E*ldnNnmZU-f%cFm*(2rx7qZCZ9ocq*=4Il`qP2fO}6GB-*yz=KEID7zlcPnvSou zP(UJR@$NL*bxhPu==INhi+VwHd6fMN(K>S7DK@-Sf_E_H%de~WriJ6o=xg&njyqDi zE&cYe^pe@EC%p2_$@k6A7ocyZ^}e@krzYg@FLcSb`qlC$2jK6N*Y^dO>9wmA^4(fN z8Qp(XLzz)@4`k`rj%YMN4UC1D9ym5%M+wmC`oxea9Ojq{rA>O(HN>1e>OzBrRcy^J znt;T}#6DGq11GH%#j-W@yVfj zwqJ2ig(eRn1{N+J4fI2VA&HMMIOpE^lNIYRp4NYYBq^L7|ZmY z0(Fwh$KRtsy(imBYA~I4A;-AZ#+3a|o2H7Y8a0N*U91f&d^)kTI92On&wg@{pC1Q5cRB89KD`5k zu-fWI*`QWO`)WRGa%>&!+~;2BR$J zTLmIJi}|lg1#nnnfBFR2VchOtTv!H$=+k&X=2gb@#tlr0>{Ix5bnMIQD8=IB68tB< z)+tg1*j(~+>pF9fEp(D>mJfISqLEHy9fC2zpn;- zvBe&KjBY(|aD9Pej&d6(LuxY%qd0G_3FFMOp+P|~Q#<4cTro;^5>-c`almPSTNU$o&FN%a`q4Jui_Eo^D*w{l|0F|FU-Q8S}ui; zzu3K{y|-Un@~6rU_;>)lR-4>Iz8gPV%gs=SL!(ctHT<{tQJ_(^(TADPC5rviqoYP` z$at{}cU}OJ2`_9!A~>%6a3Uhm)j?(;S>k4oBa~B>E@v4=FTyvZKUoa!kr%Cb&<#ei`Bf8L+L=X$c1^?7VPWDoh$Ozk!unhX3QeBz;B$Si56c+ zabhiNKIFDoXgMZM+GLky6c55jNqbT(Rq>mOl`+QiPS}JnK}dHm#{Ar4 z6B(UBLrJS3#+HA1m+5!*#)ZgiqSa=+DeQw=J>6YHtPeZK$LW+JdziN5(beKS|Gn3$ zPOnA(b``dJAHz<-sZZMK*xK+Du-NeZzVEBSUbjzo51c)(ZpsYm#hT~3x2wqqSzKMf@Q)RWv2dzjzQ+$a)LXyU=wj|t>WyN;H;^`i9 zccL@_#+_1ErVZ)5uaH-&n%X@b!;W-OVBJcE0mkFQ+Hen_9E4SEqA=uMBdge@KBPR% zj)yX=$J-+=nlP;Mkto4Xp}2ufIh`hGq1~mimLBI3{3`8%w#`)lpS5skCT4nEp@F-U z$|!rO@(rwg)DE2M=1FJ5@bPCHWJ|Dq^meYF@_-0B38j zTVJQ`>(l5DA%OR;Q1A71mSdg~Am-Ev4`6f+_~MEMRO;bITfYk~kzMIySekU@2GUsu zE<{0+9Dwnx@8-pu9xAK%$OanIP=F~#b z(olu=q-epO&sKQx#hr+ZhG$J+L)=0r^{}i^bwhK7lyDL8{mf9lOIXs+8{SVSmhKXp zWoy6TlXsVoKre|o;oGfJB&VWMyyzt!g*{l8MjC`uQq%|@W!np{l(37Eu|rZO_dThc z1M3>*Zk@gKGx9BQ$$fRAYKZx3BtH}$v7Gm5NO}IrR&(((!;-z^_5M22d;a{al=lx5 zfW?Q)1XbYi!TIS9P8oQ7Abt~({>K!~$7w-lyIj>*oikxdhV5_xJbz zo{q1}I`-)FTO^ob!AOLW01^|RgQz$H4QNEb+24M6%{o*GZruT1MFvjoE^HIVq%#$| zXpk!^TFhHYh3v443hNjtal$|5_UEb+)L}{PedKdT$0{)Q#to$B=5o9#_ohO&!~Rm9 z%SslS+0jZm<8YGnx1=i?A+MVG?l0LYl;XH2gV9n{YBFj&GXkmv+R>>=;wc7lL-c3u zT8vx+ofYqGNv3z#C~nZ&)%brIa0J(5udkU(R!paIMymC7G4K}It|ZHbfo>SndaIo? z4K}|IPgPGB-{xj+>mILjtbAW~*>ctnI%iLJT5fBsF8YN0jrI=x0oQV7LLXjgvduEu9?V6AC4~UYn>~Ur++-ldFbGU?Fbo%)4+-*^C!E;8&zTww4o$Cw(n63}W0F zR;*Z+yQ5Whe$_F&dT6+sMjY*Q{lm-sJt}^y)Cd-^`IOyFA^C z)wY=$K@Y$#easp${u|)%-HvZ>wk7NG-Tz;_U&es9*RglNH9+6Wh-lW9hJz!PW=S;| z`CI=$2*Ninb%X-j-A=ieRU+N#3(?U+UJWG@vb7{B)Ln3A!w3^)Z4nr3hcR#6X^$bw z1PJ#9zDSX`bnG#o$bb{zi(><3*r}tL9iG%dXH7DnIdjBl5s9qcG>T0f_0GXGdxibD zLP9`a+?iOT|0zD>p|i4=(;T$eJL^la9+Rp)PJJHg@^xEdpwC)e{=2PbdCObDkm<4= zd$nY=g43pR=^IX@YJFlq0h;kF zItmU}EJ*&^vDhMcMjkvXj?9!Rijk^|V!(lZ&{;sVb2MD2vE;_M$Xx>Fy?jt*1XwB> zvfeX%4G z7;b)Y(r`2aY(>MuhbKbv;c~MLWf+W!QfR+UPZG&GP&O zy*YB8E)1*9djA1*%xas2l)Qm8p=z4>546m}a$H7?1b5sGjOE$csme-QtN)k+GO$fS z^&eAsVucfS`Qu39Dk6zF765@LO*7bm0wR%I8=C#dRH9Q;P}>G*1O8;Qtre6xxE7=a zxZ63U(i|DwjixtIXu=@I%CSEyLHk`3EUxZw!Zp*xd!*`{1JZ~Oj`*>{UUWmx#_0RW z8QrUBWpBDQITI3{DJUp{E2k+E+ha&=hs;NK36!BJW>K}wI*iZFja&p!R?sK|5yUjL zp(nyhW%J^o$;nC-y*LWOJNgrJ_|YU2U4%3htsp9kAN*>3LYR`0wOw zJHa{`rnCI1Z+ z>;c5bcVGLAz4ko=JYQ%3Ja+>gKii(4zx-$K>i}(I?|Y+c&tGgAZ$H?xT*9c1ejlGewH0ppW|nHIjo)V7V{YXgomi;mA+I>d}ay-|#| zagUKOD>gte+2jpl&m=L22*5;$g)0pa55kP_Ceje`6z?utVuzDc>!i(~@W^E=Crh#w z5`R-yHecRoMEU_#k&9Z5gE$fX6`pkN_~~VmKR;6t83f^%w#7*69vvy$5N7 zii7}9)$@MgdExviomH3h=1`M0cah}U<->UXv)K~bs1VrUCJc?OIC4LlUIb3n9b&EH zMqa*f>Z7_4Ld@>*!`DM47Dt@I9|dg}8n{`p%38&P8oE|mmQ5vXA&o?3sfW4Q0&QEZ zwaZn8NuGRiGEVp}f3wqt7`1BTxL!4;2%YHlJ9hTn2-Vyk=l=HjzwN%>OrXGPABJ!5 z*3ZuQ?wx)S$2EMKe`3EgJOcE7e42bt0hkWszg~0MXur?)XvWMT%r%q8)FB}-Xic+# zYoG=M?K6iUA;myKfDTM*BtuwYL|9LXqa%ZzNP{}Wkf09IW?6kKpL6F_PI(Nckq^g@@6iqWwpqBE}=YD4n%wi3!WjtM zL4r!ycVSTFML3e#GY}eA5qaP|6vV|iZ7@#)NTV`SFr|eB=z7!Bm`V>O7;-=;uT8w< zh^A;)G6O$EBF$A$1yGc`?c(@JjU(V2g^+_VSip&LMuX9$PsEPPu&bPDNXonn58aFA zD$e=PACaWNEi}D$gn@bMdzOnEbweYa7dN^k&t^V8hSV9p7PGaTsM}Zi8irQ~LIDb% z5X7ECH(Uvy71p8}g*49U@e(XYqq4f*t%e#CIX;{UE?$pL0T_YxmXt1m57*P{u2q4t*MG^gFEhGAR@$?*{-WdZX);9C zAQBrtehMNadTAO8F#HT|*0f`A@lqsk@POa_tRPY2=8?P0k>L*Ekx*@dm_QMRSmCC^ za452mbT196G$Tv~6fmfn$U1OB2q(MRs9sHob_w-S<=?I@&pMB4D8@_JA$Q8-LP*BRUfz&tLR*pn%HxbPtAS|9mH=uq=1MhZ@ax@CdBbp4$O4k<%sex zy(mJBdI)$hfw+36qwOM`Kv*p$&=6pD*OVk>$4*uo#2I{$ta4FF%BIx^ZAZTmbBZZS zcDa_pG>VywyNG-T&u=QM1>d$RtHmw1i1fr zeDVJd=qOs0lE%FURb860TJOuGNuoIOEk-?_N=`v#g9Yw=i)pjfzc_LwTAn97SP$wpu@ z=}-*RvZ+{RWRb)Xn`dI^#b0ukUdm}VWF{c!_ML0`FTUf zazujxD~?1s9Jscbq_u~ z`ASg3b~Farzk^f#GY^9QCL+#c;xJ@0P7}IK+up%xoLCWgL?x?$?Sap`>{DD$6~z>p zs3Wr=wVbqSAhW2uoLnPGomL`1p(?YcyIQ)DiRbvRq_Cvg;tzbt{;fBexlEM%!)_3e znKp{g#+eTBaU2Ac4CaaJK->$TB&hN!H{WE+;xc?i($GZn7*Pa?si1ZlB;lG!w$c75 z7A(@jmtb6kefuA&QtXn!^Y!39acC$C#q*8uLkRO`VP1luj`$%Yt#QI@NaBvj;_}Ug zoR|$D)Z;-G2j?`A&V?GJr|N?8;jYsPamnI1+tKL9s_vEMkwdJ)hpE%kGgH)Z$LOxk zw@I-GDB>v+l9#$WY}n>0rM9&m7%F-`Yr092pNX9^6hG{keHIibHUtu6bW?Snb(iEv zAcO#YPQV>50x@PhgC&1ff?se`xqqZcDkd;M6a@2#RQEDqh@`nMu04P>yD>spoDjsc zNmri`$6isa9MsjTd#H$t+#=WfD)aXHCiy3ku5ycE3DdR!vGv^;k(m6}Y72P7+8ay@ zZZQ7DOX3Se0hE0XD2*@S@1yT&SrOs~&JkQNRB`)f{Dr#0af>M;?B^(`5l1By5qAd= zSvm;Zu~~RS>-OFh@kQ{%e2basV~FcDqBobWJ9No;$Z7W0ys2M1V+e3umx1N5SdvP3KRzH!U+UTtjO`mjF?q&PxhgR>dNY?*|Tso z^3E>Wu=`9k_3C6^A9;ba7Aq-5k5~)fA)yV(dVwFnCr$w<$`^X^>P^_-q2AU6WF%r}?OdRn5qk@^WTOlq)P8F@k~@FyLpzP=(u=)4X}8OQ)i zBUXrX4m);yEPNmoCBy;>Wdutg9x56-Y)}XHgC931gQBb;6)BmDOEH`ZgCf7nQQ%H| z_eD-^nF_El+GoH^*5zuMYr&fLC(Hd%(TcC^U$hqd0Z#ynnix2ga6kSrBFSV@GvosVg|&+IO+HCnb)i^nDEH19{S%&v&7baDD?3JsMG;>G zTnao4S>n{tsFUu@;lZjZ3?a<;(xBD+OyD4K?09jK3)>1P7RCF`s3IhuiAZsSi6-~W zLb1U$#yip2Fz_7Ic$q25(W%U|(jyaDqSbzadGakeD=(F*27IO`+_{gyH|@Q$Z4RH> zml3d|zjKx0$07F%SSWk{@&@)ue9<4qk)Hzo_5rB@;8jM=%QE zu7>bC;G{@{WVWLgq@-SP!-o|@;&Av0Wy;Wa5MOv;KyGBlYNUH1^-w|rfmx3jLA5`1 zsjZ_-lG(N|@bc#{pG%*dI9hT$1|LIW_+`Y##m>%dPOp<0D7;^YE{^I!QVi5)iQh;` zf+2Bi-pQ&elX1ATU2XO)Y^&3-tMM!VZeC)j)uLKN}1; z7_&MUvmdC8r{hutXbTn^h&G6^rmS%PZFjS3?4b%Z#)2sFgSM0wX~uV)qX>Nrl?D9h zG#4KIbw%<@#3N3%0#|cN8JX>H8k9kshNpu-eo$v+9LW9(=wjye%Xl&QsY4 zb*oC=Z?Ev{*DdEGrPJD|9>&&-xeR32W-}@$wv2d?!ADC|lXwB8E+Jy7l2BhlN@$Y_ z!-SsGfAbB30=nTz@-4+7RrF<`=1U>x^HEGJ2owp3V96Gke_@DRqGQ0JF3>`#43SzV zR2-6OONd5Dprarw-zL1mmLW^EkWmpM$B_~x#VQFXVwGkUmomm#a42x8wU{YzP<%@N z&FfoO;8Z{dylVlzHmUyw+O81KIv8~TWOHcym_vJrlwugoJ%War85t8AbU^Jp8f-s^ zncIxW)Y(sjr43EzYJ`Mracc6k73*Ii+n_0)#bB(x?g+(aC4Z3h(;+B^ur= zgApE>X$7ecy{7RX#?!f3CRmm8(e~9zAb*d8q(IE0_qT&L|3n`$*%n6IALQ1gE<(Uw z7$pE@VM?A1lEpeW3&S<(XNAtVB@}-I8;s;(VIiD|5lz@fBL|w)uLl@ML5N%!vQkWp zu>O7`pcIevOQ4*VKCuYy9)PB&Mpr~T3F$~INNIOeW;3hQDPr-ui(^!@4zlLU$Rs;& zv@bfVEi-_;sy(mh_>+aCzRO2%7e?vW@kOnQ$^Ju1)|qKH3-k#_#%(84C;w4CeIx%Ss%&{@l>|p zNIl0;r7-VW8ZIYtlIwnTYYgjo{@y5sapKqOPfL%)LoD!7g7zN0#h}CFH^xORp2AI6 z6&IOXZJi?kn)v{Gv(%}WGx5+-QCye}G0nhG^w}kN(V=cwm{Fk7K|u(ZF`(2yZs?iu zz|^4g+2}w(gP0LBz(RO}X+Q%42?k)`=1U;Lj01~Q%@VRuB1~ztQ5gD@*-VkhT0`K- zNWjdX5oyA8NFZ>-Aa;^IBvH%KS@1-};J@JTGD(dq3Nv6_)gY$9K@o_y7uy-QwIMuw zN~3-V+BfW(Bnr}qQlu?#F1jnjX*H!4pDm$qgK@&>|KJ7Ft?G<-BY;~XeF&M>avmP>H z*dyiS^zSeJj5ywG?GA35bFew((XZ5=x)J;gc3Y}Kwz>4q0>4GcP3^t)>WP}ZtR<&* z!r{C7^?fb7hS)?|{#wX?$F8s2{~Zw50QhiOv9et*Bq+`+KBn02eH3z1?{RwHyB6yE zwK*L06YF@Se$F)lEsZ#4CC$tXl#(EzKSX<4a-e!pnInc(bbNleU7j(hof`rqpUPMp z))F*7&KL>ucYr)I92mq;W@HfK--yg0VCX>WDLfDh@D*3FId(C2rXoSG?i7=uP{VK# zamYvq_{AyIL=d_N?!lcL&;Vt1DxL)JD>~Unula=J{@)Y~H3Z4xcJtQOXQk2#KeQQS zP_ww%vAmN0H8cVO;D1FchWQGEd)-d_o-+s0_vn%(>;?f3;jS2J3jnnp+!!y2BB}VE zvO*J`{LLngdZdxC@X`^6D(MiEggD4PMgeb@``clrj{O)7WKPSf5xx>P+3?ae zC=aN}#?TdkmX5kfL6_F0+LEk;>PjD9wqFlPSUBhs{cAfBs83^UauC}#y=7HN2`p`9uetSP34@y|AY)pkPkwmDx)QIE zX>awt?yu3@8qhZ#@Ohp0s8?U_?sP=VCI8%;+^h(h`BRfP=Kff)ul>8WVBO}3mV>9{ zgicea7?a~|dgkINrf1xh(ZvZ-$GXNZWYn_%;pi;eqH4G(JV6ZIIHW^2%n*|5(2aD* z(A|V!Lo1ZuiqL2~xKKii& z1RIPS%#}{5J;kHOmiyI;C&Tz`Jo8!puT}y@dN1R59THFfp6JF4v$-%}D3v60Dr~kL zzOAxlA!?ZH(samq;5+L4SM|+#dO^8zH?zwAjhXKO!sXCFcg;G}Z>sahxsYZ`+t%!t z!qXP=Z10NZx=h~hj;H^gvlw1;AiC4%>U{K$FDlB)M+^F(x}%;3K3sQY@7g?4YL$5{ z4dsB>iiho6}O+Gq0bx2H|g-gFg{ev{`aG_irw!bG?WO0FG3tJUrP>hA7Eh7Fjn~3pBK(8 zFS6o;oWT4i$*1wl1-@B$OtU?_;iI|{HpblWZ)$Puh*OlSgP_q*z&7ObY6p?rli`$t zazV(yVfRX!r*bA`HklYO-fwx)K+j_`TtYA|Z}60x6xN9JB%KTv0Js2zB1U6NB#Ap~ zk<3hNy4%QMJ;nFJq>0Z|1#sG^2AvQhjGf%ID>kW8;uwd`bXH!ZfeS+iRNXDPd_&5Ege;<%W+ja48tKb!Is zL?q}!Nu=OlAh&=I1E}?vAJ>w> zL5N9*FY<_4(i!rP8rB_ui&uWGlxVD`cD%UvhdG*`(Mh+QZJ)CrTTsuNcfKE%MrX{w*kdnqR&9`kiX65Hor8h`{UCmyGYz1I6Bx*?1WmGNmo- z9P*aRwQyDN^hVwIrqwh2(hVEZoA+|myqwk3Gznkgzrl zqJ$f^9QrBik2diJ3$*L9uS!(qk2+x_S;piT*X%-etvKDVpeucCwI>!K$%-sYeatXs zLua-wky_#8ZYA3Ebwh(zd5D*k^EL5&QbNuy2W*3wtrgt(HTeP_fl9=lLm2& zpg&M+BxQ=CyGp3dc&O46nbHp;VHO3ry=F|{+)lL%L?6RUj`0;;pRlW@`P44-QpOKatT1l1%a3q^=hEa^v)V50)W3krQa{!wgsbf2B4(G4 zNGL*Ox>9Y`iEnHwaKAWyL*3q=Dp>U`qa4T4BDpZWz7(E8-)Cu|THu4d6 z)gNqoHPrrDP5v<5^VH5)pBgJ!;~*lWF5K|d*HwoqgXoWPEM&EwPvTX`shROgs+0Bm zk-wnc*}A2j~m}<4#=$nvzhk{>|9=(PpN0HCtNk` z<($oZs8!PLk38<=<+z!@GK(WsiDe7_b;SHAt`Ii@hJNQgRtFLI| z2&~bR#kyo=GGMCXllA@jmrDsYceuDsud+7?4%U00Q&bDKCZJ>5m{PA7PnfP};hSsD zjUB!n6(vjb3m)f`p>+WPCq|lIaU%CS*_f|n{}Y9eiMLP9G{ISK+&-ODt9ufeK2r3h z2p=<&I8Bw3o6kGVK~*35X}%b6y|4S1HW>$7ju3=`q4h-2A}ADv8IN;->Iw#YWv9gj z6u~}{gUPTaN=A~u4;d=U4cghg&RNH+G}o@KFNn{;)g76BUe@WtF=#YUK2@yzNq!Jl zNv73Ti-SdP*XO0(=*W@|G1>Ybe})*!I+-^vXVKQh&-HavrGxo_F_cLrnY*v`6*NTX z6;muqo|1rNk`qa&gr#Kan5)#S!p9Yek~-BG>h0XWiOM11EZ;6Ceq(=Zu8)8$Aaace ze`royiS#7c@#b!7HD&2k`)--$JG6RbTXb^#So2h-tU3r`>N0{Ac!1HtAHfQcl|s8-``_e?#J8TOxlodgB6O?ND$T3w=?d zM;3Su7(y+!qJ=3J5g}JW<5ZSn?WvebVgt)y%~c-3mTRZiykZT(VqQi+mr)GX1{U;9 z3N}`SiBQmK`F!#nUk0YcQevy6{Z_Tslx_mx!zpnAtXN+=_|kT}BRtlx6ypGW^7Ns@ z3q-Du#;67mKFvE01YtUK44z`!X+_VlZ79q~^kafNMm!<;&@Rj?@0jzIlyN%sB?GCP ztfi;<8>_%rHMv>seabv46 zH`6J?p{cb!vdl_{?W1`xcfMi_ss4~^-DO_*5FMc30DoMPki8jgocuvd&}{glS7To&(!kM2Zg*a-{7RHmMJ579I_{&49g(r_^}#NuL1T=e zvQ9?U=Lt=X(go)Tcf=~t+$dGtx^~h#@TpcMX#s}TGf#Y>aPQ%K-O+9<^(9jK6os?I zURnCS@6WxjiA$@1FD|aL144K#Ou}OgHfH~+YJEHm`ZsxWZ#b0wIEzhXPkV%kzyz&Gr8(hl02vnexCo~WI}Y5F07(2cH?gbL)b1vi z!I^D?(Dkvqz)n}WsEC+!dU!a!!skg89$Y;tVrxNPA?ARFv_3C@`wLN$mqB`bVm0jO z!znehLgRj=5^*gj3FG>W8>#3&5RmnASWjnD_WHT>a)7GcU`$8#m#(CARYNHmZnA{& zJn{kG@_3fd@k8;5LWUas3VYq;4L=drCAR1nOL3}=3Z`;9r=2Mu5x0JJIV%eO<*bzz z#l+yXm*Ngu&rPqN9q9NWr1kKw#ec61&gAiUAJTUGCkhvdM`MQSq1i+307oSfPpHe& zE;A{@J%XX_Dt6$exo?5N&)<_y{X<#QgzOTCa^N8m&imLP*FV!`Lo?dcad09Tv?V!G ziv&=L-7mSb*{=@Bq9P?4#7L)xJ25hXr|u)JRQ+rkL)ka7AX3GA3I>xer3~A`_|%Uh zIgNFM9B>3vtB=zFIaeho!zhh12s8hw{Rsx)ots_%A!Y?G6p433zcyuS}AIpS$3YPH!;r$yp^M`B%L4ndXaUH2vh)liamMs|DK&mb3T7 z0#;4k_S5rCg9?=(_V?(ghkR;Z=A756a1$-N5m4R?p+FP)PFtPhuiVq0yAY0tTtB

oVR`hFv8gl^(d%}w;sX`8;b=Vs2$ykK1uF@Eu>;i6hZ2(UX_tlUV1tuSWyk95 zD3qRkqvSB4$3%F2mrcjc-9%VsfGKD)3#=y7URV8n!gIR1N1W)4;U`3l%d`E)>#)F1 zh4-IqlD6d0o_E`DMTAD)Mo9>tq1xZ2W}krC9-}+0Z9Vy_oQw^ zK4OM@_g$~CA@Fy!az)XhgZRZ>@rG8|`{rc)MLz2Pa&-6`ehS!^5@t_7zEIJ_Q;9&I z46=teeUkwWgi!UvREbrvfYSyshAXc{_{2b>Ov~9g?T9ubK_gNpiXn^_#=l44*Ca%Ce$h{b#3fnYzp}r~8wudx{ zyS^?iftxbDN|``F^O?XKmjI)h=OEh4q0;ZLcMOX7XjNfpKdZQ@Q0FAm!5Ocal}P0G zut|5cwsb+}zbO=F@g(r{_wC=~K$^veQ64rE8GWKc5qNP!Zbe~wt{E}4 z?KGO~IS%lo!U4n2VYpPl@R4)aBpi~(fs^G6EM`G9V57XCW2>u(CCq*@C8z{cSrcd= zqq5EEhw9R!XmKd5Y9@G%51cTdzO7iUb4!crV@vu)%%~d$cl3i29PJ*`DyQoLX4Aev zat@5WAP0=WR3-$#O1n#m4NnDkgz#(UaCw9V|0}9@KpBg5m&7d94;{^ID^t?~-X8XC zeTJz*_bUctf%S#S^S>q=r|-S3***t6s(*g3GR0aB2jw$UFT~>fj%lOblru*c=jj5FL^7aPb9i-4}ifCRL)VfAY5}ZkU3lc zrU%l(0FVdt>&JtP|c z(_1+sy&bu^%(HnVPEJBWXH%w99L>z-Y+6}!WIL`|i=iu@c#as-sLw<`5?Yj|d%p!k4%) z%>}};a!pl|RwthA!AL%5A)qvf%gUc{)B1~1m*@A{O~cOn`pY~=BCV0xkF51B1$Hg_ zGd{PQjZe!SuRl5MlEqID(5AkWp9rh7$B*M6{P14g{}k}}YZCTd)si2u#v_293ej+T z{=t@L{roTtKq&@N2u6?Mfx5*81A|e}@WHU>kVyblmSR{^Q!Fj{aB)U>zh{bhsceEO zsnT9Z1gP0|7$I^iyr-EG=e}23PiBdg#74i~o)yP>me8x1SH486gX7dhxGBv?^KQA; zSUYyxtt7io5F$UH;7ocY{2Q6YRvs{Z5cOsFx2Od*t}+({;UVf4ZVsw*^Du7J4rNWN z`*p9^E{+s3;QDcrLCVJ$`jx?U6PKIAf68`siQ9jz;P$@bW#7LWg#OG;z|RGzne&Tue;Az(cw98Plv(sAC!_WVqoKcnkgEL)c79FhE!ic)=;BHh>53#hJFko@gZEn zNHa_oQg~Va7TPpQ&{qEzK78P>nH*pgY)(Ur@&i{W8kbEPU+1uES4L?}rz{1n1*rM6 zPNpnoaBfH;t;AnA9v=D;NJOU|%@oRdxGE4joaJuB9E)&XnO38}6c8X&)i;k4sEWDJ zLa&x#mOccds3;`z+*Z)Y|GOBsBOYmcaHJ0P-H|195i=BiQGq=jHxr}(%eJMeZ@Nm~ zI;X#cb%RzZT*C9C&wms*q~P8iPDCVdXC)Jb=$|bN)0pyt4cUik1yZ5@t`^i7jY@}ly;^d$q$LV$=4zOzCc;S6FI~>3 z&st`Rl4Hz>*DCa5NRPHu*a#sTtLTV0*`dLP>F60ven{(b%F zNk=3V6UQf5mFFY`Dd92^d2>jOd|JQEkT9Lh{4Ky0 zzZGf|X6`ce)!%{_%^afGQ^ywj(g}SccDM*KuU_r{z7P^@gMyQ=GfU5X|J$;ry|qEW z3Q?M8|8nV6lm)xzAe6E+ER#{gyvX=7!lnl9pE1fZRz?C$iq$e#uHH}9^^nx)>ZH3> zuH0#EpU;;@u|MKsp0e^Kl6A-t%X?+-w=EvXVJo~;K=O0htyhc5G{ z#f$5U|3u*##x`U%8~WTSJaJ^tJugX`(xr>zK6{tGwNwWG;^{J!Y0KJ__%!P1+}Gd% z%4D=V0M?kAp8RXejeoL{+WY5S`r?!99N8thEYdy8P2@TBG{Q`u%Y4qx%#IK#1;tVW z2VH={7SD_>GJ(Z*ijrn7JyqGlm3(yLlEWSxFT=F19_b7f^5JS_Z>)AbOI17WykvW( zw?pt58+&E#HNppWDgxGLkKL=A#>JsboyuHP@ogo$iBvGAu z{D@5Qt9GTKFih{|Iz0+!?30-&%Iy=oKfc$t?fXu~lS5?lH9i+ROWq%|))rdqtwM7S zfBlK}mr9KCIBs2M8_yj&EMNADZd7@vXE3aOcygg?qxeT<9H3H3UZ`0zu8g5v=$VhV z{QT5Y@u@*Qz;oH0bn#V@StO_|;|y8EAc9~pCKMQ4)ep=<0rWUPi2+eCLgI4A5}8mm z`t5ja*I8*dZE}(595Q5{d`P9-FzMSnuT>s9qooK3$k*~(qNLlZ-5(>byK;y7jicKy zRAy;}>+-Rf+|X?v+KXI02?yvW>0N_eNeMEg@y&o(a1I(qG_*Z_Nt(<`!|qmiQn)PB zPi(m>zS~BI&{Nu^?2&U>G_vHWLhWaG_ShhfVk+Whb>R-Any2;6RBhR1h3S%ti z*=~U$bSVfRH25k6IMO4E!F#~4ehvKR9nLI9C_xB~l1$GiK)DDC5iXi=%8$WK4pFNB zy{?05xptj0{3NF5;1cC4&9y@t~TCQvMV=@mmn{(>?ZeDdBR?2qd3GPqr z#rTeiP^eWI&+Rjakg6*&51KjQtkBoHH!2g`f|^_9W{v_%)1h&`ho)YMsWTj3%h`!W z`KRtO@hIp%_^{{RTx#Objb$|Q@2rT0&Xg2(2r5KN(!n=dZ8^Ump*l%~9%6p{dt33> z{%1$2=GS*w+BxZuEo;eu;FPhfxv!o%hFd@o)m$*jOMcSrfoNzWUD4$;qtkI+*7%dDb4UXp0BT?y4e(X4B^J;lNvjX-ZFJHVSkip00e{=s$2vN+AOp|GdG|%LZN=c%i3b16H56}r+;Rc@cXoY=i-g~- z-C&4BhNR~-p6N)UKYy%JSUM@ocy-%ECVBANepI>3RnBT(PUxto{+bFItqinHAWLX8 z{%E3eiRK)dflB%l+%{6cm1n%AdE&78HIQcJa(kyECoxtk>Ot#O?eQB8TFH-(?GzcY zFAO#>DF43?b(wf8Xr=bw=Jb>D#MXZ_1@r%R3d7)*%I8j@OG9%OX~*j)J@4kZ5P)m^ z(2?nOm{w^2YL3cHfVD6~*gsLU?wkkq5#}^63LfDVe#fH%VWuCTMFNOW0nFs+%n$%A zeN(?{z?|Lsl1~ZZ!UkGxfLi)nn#nJ4V1O3PLDzv_WR`?VM~G#byp=}ao>3iLKO98} z1&g>9dB>T&Jjvu(((xjyUa-*QDOL#at4gb(cI2#gZIAsjoKcq_K4Pd>q6HF^PQlBh2Bjs zgucOp#?^n^Vkk}&)O#$9Vk>gB!RuSkGfXZDm*R^uqD6~)0~*}^8aap=3ZQjWpv6^Q zHV4DC*-beuYv=$e!&b)Q=&13k@NgQae*YOC^SE~hXq&?L-gPRbEX`oaGtpiz|Ym8fjKL*OU*G)HOB%EZ2_zRi@||@K6G9FMG`;( z@}Z;e09aOEUt~0)!-FMT%Drv-KLGMT4ZjBziH9IX7}14khBy!y5dvU11hW%6$8p`)_p$e2yp zql$^$Yptw0)82hOuGK7Yyk#wFM-MhNxa%|q>s_2k4ob#^QE?!gf62gj3l9d6alznx z$BYfvoFKZSNIRifqa~>il&unvQ5>jDKkRDTLsIkZr2AXzdeYCe7|Q-MihN zS+CP~Eq=e`?$&KKw$e}UwEVozeRlcNxid#`t!o7DI4FHhiq^J_Xy;hFdh0PRN<%c^ zZ!rD?;|GAuF-H_L3Gf{-RtEzA3Ib_?fF2kT0}vn#3=2TK!DI!30Avn>W6T5+$SXQp z3)NWGnua6-e3vdng~ja^D+Xjwi>S}sWcy8N^p0F@m7Xhx=)J1E${gZXUk!D9LZYlC z+FfxrzVW|Mar%>(yq-zKa`~v3gm#jJ!ohtY#MwmA37S37_SIp;t8iRZ7_L&hrmq$h)k)Xx4lM#BZRgdVL-IwRJNvzFt?ItMu6L$$59fY9{WBWd z$M@f+>-SIZkLeTt`{D%V5BFGQPXpLvaQW>C(0dPVAUU5n4(08``!MGL+`YJYrfojf zG$;wE`jpYH6pdTUB@9)f3)fM<&CVLJ#8ZcH8+K*52Ag7JtUS%-rO zmEf2(6EJXr1_fi}jPgtvap~}bBFT#|25ev;DGC%K0S?01m5x9mL8YT26+jiSH&ZG? zhHMp6l|yN=q~={tx;Lz3=T2ywUW7;(x(l(DnxPB9rbCadF?BT(4a(wX%M_ZF1k8{h zNyQ^D-8xZ(81PrZS1B1{Ja+KBBbX@txq-w;-5im14cwHY99OQN#n$hQNWl&r;%9NB zfo~bcowLBqD0<%UeS2G1)qV4wQXOX2wNFi~+kfvF)+u}6-r2r2r$3$i#S|bwV8HkV zic8iO5(ykMs^ZTRs-EV%yIJO}xy5)Xo5O*KYdN$iVUI$wU_CIf6fr2OFt9f;6qGSw z83zkS3WeqtgQw8T3T%R*DEO1Yk(WI)nF)%z=`A22f+tH>NEii%Y>7eznnL_lXK5}d z3Zy(q!sx$`6}qj7six#r_H7zeNtf44hH|-M)g;*#!tAo3ViWMQSEB*&W0T~mRES$H z?PdjvNYLB~LoCh{q*N-_7bd0UQqgyWz~=Tkx(dT%)>zYFSn>CykRnTqJlr?YpE*3T zr(X{>Sk;O1-_0kVRD)VZ&VC`@ZB{<1Ofv5u;+y!bubo5U;=r3DT*82$Kn^bOqF(ol z3l?%6QQ>=1VcUJuDlyzd^AFKXF>D4C44|GGQNskVQ3C-15N?m9K;PUH;8oR}eqQoJJUq9EnDKrtjG2kA3Qx1DNt@ldnf zM1~*Bm2x>ooxJGe_0!VQMH|JEXw{`Ov6NO&I7F*cBU6lQ?z7#ldFJ|$5?E8gjQduF zXmZ=rTl=lOF|A(J#i^TPR>rlB?%uikmsk78*7uy#;`sQ+A<+RNK>#q6Fw#f{=@)8b zD;U(Fh+{nlIf!y$_AfUpq3%acVoKtfX>1P7*-GC)J#b$Toz_n1Uq`2s(s>Mw@{h#|>35*;7Ps0BIr zNn-j!-6neFz>Gd=G1t2;eV9T>IuLXi)f&sn?yC&q^s7S?3dZC?R%4F>yP*IXU>D!dvO7bsnB~5ZeN+5IuB{>!^*O!LF_%b z8_l(>V}3LW=iar)_|ATBUyNQhiVZ{9Vx_Ss_`HvyzxMfWy}iHwRAVHY23G@$W8?y+ z5Fu1yUL~dhfm~qN3nmL-8Ug~-1W-3HJqN%rD}?}9z+?+d1^{ee8MG!WnPEjpr-6l( zG%Zz`P!J0bPb8lL0YtXSEG1h~xnh?($}=nH=_gbLudSADtjcvq7j@iKwG^UekCU?7 zHuLX`35OuJrHzs$!9QnmNl~c$It6s>Fcr#qq-asYSc5y0%R7ABuTh~# zQoc)WGSjFShNP?=O=vIZzv*Z@_0H)Q9^!5<-S=5P)<4y?d;DKC*7qjuU!DATci-Oa zPcOAKdSf>Gfi-ho%qS)b3y4^K2zWeDlE#ZQNw}q5e^HE5Ul~pei4pvWgMh&dQA`Dc zP{5cDz`caAWJotBzM#>tYtSD z0)aKf2vtWhgeTiVYiVgVk1z{->&WJ#a9e2LK}*7d8)Rxe)-SS2G@)ob{JRTTvdfb4 ziaDMR(!I@wXetym+f^&6)QZcUXG3mRuAaK#Jf%~s=R)GStKcZ1Hmg&s6Ruoh>lfZ( z;lh&L<*5T(v`Mc1O~bCgudaNV&i9<+n)b%`i$(dThkfgQ+WwZtuS{mz%_iQGnR*M1 zAbt<|-4mqh_P6u%{oMWkDm_edJcUy>7=98}&MP1cIvc>Eu#8SH+&wUOHUR+uKwumc zn2ZVw5zKf63APv*F+`BC31IXkqjkYAHMDae6BiVrP_dxV0U#EgU|M|C%K}F0dHt(cKDOK$J}qgjs!|QHuZ=|C-9N=QyW<##Z07T{xQsji6+Wdpf`}C~ zXj!BGMhQCBk(G1zn@TrMeF>B=`s!0pvi32x*215yVhre0P$m_hG^yn$ZxgtF*aZ zM=5l|;w^x(3d=Jrc4-^s=|D!avDL*0HljQtnOFC$ZFyD#9SUT8-v` z!v$%nK(0ocEU}bHb_FIPB6>Af5oZ}rE^eVYh1b8=+Oh$Q)$C4HC1{^Ea-j=;H zEp6|-?)Ba4tHq@wdqd4Jh8xr48vpy^1ndv@_-9T7xqEQ{O=-Y)FK! zXF=?}xTfp6YvLuhef>@EyW8(K{(hzdumIK}P>6syEFOKgJr4<@q^6W*OkI;q#VBx$ zd4M3p@Cr;}0${>i7Yqi#K){p_%mM&BbP!AefZ{+E0P&z-FaiK%q93#rbc}kW)B@gw z2z7bHivk4CiA-8!!^5TRa@A4+kG(?0G?g!63`rzeG&?&5&b{#4N@NeZVYkqwt08jM zBqj!`kb~#^>quV%qal_tGwp^*Uip z-IfP)+IR8WAxRcCB1GF_yI8)w*87JCZsOx`=gz)&^Lyfy#;d>L>)Tnx9cy3Wk+rYA z|G%AE{qreg6Mek)xOKd_}NsE$Sn4k`kiy#V^jR0AVpja3- zga8;Kj08XwbQR1O09*tDfq;x)f&gX%AVNX_>BJW`WGrwAjSyBQ)=3v839vi`1=hK^L*Ry8m;k~>+YJyeLuEz`o6f2s(<~rzy3FC?;q;8 z-afUznF_JQNS&ZU(`{u->_HY%imEa)LqiXO4>7_3GXl_fFp>%r1i%|GR{$ddfJiV2 z0-&%K3<7b1fCvRZ5Ww&S)YKdSO>|fQkdh)C7|Ku<%GZHz(}n&}#7>_=u$3gk8Ed0T zZ_|<*QkTVes9Yj36o8?o%o(eSz#oR{>9nLkpg__>j4^(?EpeeYD=b+-+{B$_ za*SB3Ta`VI<8_2eop#|BUz@W%5T22+iFIj;eBUf%bC3hJ!Xyq9F)e`G>DNL2cOmx0 zjaqBdlIX@z{GwuZnmK;k#Qnq9W3jm;uEmUG^p-c3>~q43=J$=i{4vWapKitN+~3sh ze8>O4|An1vow@h_3%uudzx`udKJUB3|6l+6-~{Xd2hwFv1$zJh`fRD-uV4T%&OuBW zy#NMMNGXFipa8$uGS@rI@VC|$YXzJh6bltu!l_6=BBtMZ{i#v((VdzBrlXTAo(+J= zVTl2S1xz>q*b9phrX)xO0C&s~4G4gRhF)~!IKxBPnE@23mOBm9)0Z)@Oi4ok+`Iuo zE20>ggn)>dL*&)N3>f03NFW$$GsBkY=HZ0kL%>ml>@i0P1`LB|M1scvN+q|Uh;k%E zU|0%uCwVo4CNvaD8;mF>__}aBvZQ{~-^kb~7zHU5GeBSjcnaLvg+gj^7$T-nDie$t z695L@8@Idr&e$kGB$%u&rh1k8f$vM=^(;jx z!~g*(LBW8?l7PSj28DS6cIAyB`}ui#2RZA{{D9P`Tzg( zpNBu3{&VpE_MVOmjy*ii;fH=2aS|dk545;?h1H2lU6^_VYi*J2gui-EnB`T<{IZn6 zi$@q0sdU}j6hA5EFYGfJiojUPa6PqCp-eWGGZX?mxIt6EU;@%K0>d>8F!fU!KV?sO zgO-_inU)ZNgkD!z$qfj0kO6Vet3!ktVAqE-1Pov$wm3mB zhed^e!f#3`BBG^4k(PYQ12kmWs^tO+F`f0;#s4k{ zfFg59Hx!lH!vKSa34mY}b0{Dq3}*ruGDA)bSm075x?BjIUmR-XEXvHi=s;Rmp;?SX zOiD$>sLvO6S5!2uOi!5Ijy5Ku74Ik}P) zKml3P9snc^o~33)oQ1>}xskI9DSW?Q%(;6hWP;SPb28i%N-{(gV%j`9Dkj~5piBS| z;AN8z0-ea9+0r&trc2EPtJ##Q!a+&Kr7*P*!=LzXx&Pko7;pRk&;S4b^_bV$1XcrV zNGPP3;+w5E!UJipl5{#vGZ?zIH;WNvtNiR{t6H*hsjKS+(7G@!D?M))bQZB= zazyHZqig1yaT+;b6N?@*rqi4qG7%B4&=ir81B#TGm=SMG+#JhC%tQeIq(p*2Efi`& z#a6^C5P@5ki!M_JEWu)HvGhWaFhR#>Npzlt&3x@DMFm&unHO3D-(?D!Iv-dfU^ z;X^DXuC!_C>IY8FHlOq+qX`3D0?MKsW(ZWxwEYXKTOHT8h356a zcA>}V7@c4MWizcEwZb<`1Q!|~rk7#%DQaE1%$5K9;sjU#350}GhHn4^IS}e_&ENoB z0fk5%w}1;NuPMW{@BtGpkV)69I}Ii?PjO>0>0H&<+U9d|yV!kO-M4aI^>V?isuvm! zeWVYymXPGT%{kG^AppoW@w&89x>;s(Q#o6|V;Xze(%#R#tDYFYxKL4EkIr4G1y0`1 zzEqjzj#&5b!yREuZq>?awsY>g-1keZ{{LBizkL1fhiZc3N4Ze+lYfvjhO>qQGcwaq z2{Y0I0vszi2OSo0RD2*nxS_!S5F{oove3uC0RsTHgTQV}O{k&kCIcm(p&%||+b(3C zXDQ08O1+Y^^yh2n6AKyZhtUkM7~@pA1VJ&k_1=s+tr7rwJ?Q|`N2PNGoO<2K^c*Erc*tE#L@+ObxkHBhg@Hz%mHrYTT0vO}MPZdTnx^_A;4u+%-Ezey(#7ig+qd$4>nWM*P2$u2;hh zao+b{@8^{*dot?#rOzt))yL_rWBT6e>v-$C<^J8>UfQ*>cLu?sP~bpQ)OrO*SUM~; zFajhJGALmo01#5sBeGDV^C7B_qmVT~55&M8F2*Psz{-b}hQTK=&X7qB_rlD9Rg3ot zi;y%18LB7dVBuYLD2t_s8m!P|EvmFZz=pstiOJU8D&L!m_;43T0Y4Wr0I(}1k#=$; z4tAJI)p^$BZVy8FrvC2UI*!)7@sjagt{itpr?!b2k>0#>YGY%|1)QH!6lLcsPekqO z311#)R_)A`g=kyD_pzhJp45++6|Jjl;i|CY-tBh!_%^g_MtVn^8HUkYgY0U&?(*k> z)UP$d0g8lRDBqGOp@I>u3)srP00t{Efll%zSb5(DQ=mZsE>f^Gu2ExkKvitF3lV!A zEF!r8|AdumFQef)fI{06kkk;^Umvkmhx4Uc!h$U4!g5s-wO@D;+29|JmFHTJ@Lq7k z8j%=Ry zFA?{WNO_NGedFJCv~LdE#$##jv42eb?-7Q1cDUCP%7D}pRq~rKFw#mn9lfvrJNsoo z04768`U-K+z(W8OWWLGvk2EYDF93mN2ND50=8r5kisH2zfUAaQ~Pg$vriB;>n`7CoTejA^pua0<1^;;~i z>dji1*t?JJ-J3htELQFs%B79vo?W|1-Rm9i^0$IejP#ht8+XbBs&!}7iogM;Vn~_M z0FxFZP)b!ZrnDCvG)i%pAu=mWsb6>TIhRsutRZ;K1PuEwq(I^3Ae_CEgiHY)1k0tW zE>$il0=E#9SSDtL1WjW6s1g*bS~MrpT7|&A-36kZ16o(C?~NJ+APDJ*PK3m}U5JRR zPRjmJR+_2<$`J-K?pu2iNKmY?dq$u3;>a38gCs@eSY7=ndPo!a}Dcw>wNv?d-trZ{u;fQ5NWG-wcd1_b=CgcaT6L0 z&qo^iWyVsjmwEqBw|*IbStMQP^qO!L<@8ulE#>f2qcIufDvY@o!ER2ZP400SLv>KB z6V%4m6zt(xUfUz53I?)PeY&R}{4Brp8zAjYur=u9Y}oY=t9~xRM4svmURjtU!kXXV_9U zMQ_b11}33I)GY1BukO`FX4&seLifBlw9lsgeDHHW&NE!&dA9!P^SfSZYg_REDV{O( zf2zH%&A&xJLC2U~ox_J*77`|x3A+8PwY?miP1S2^yQz@?60TekqX?#Y;&`(Yq>%bm z3u$7BD`6=(6@-O~EJVyOtToXxnFa#ccWydR)M6QvV7iclAfrUC5ya^KPBNjB7t~%V zZjuy=QGIF6d6f%!Dag>)+eVvV0O@(^vB|zRCVb4TqTLkD42nkP=uzLfwoMDgeHTtp z^}0QU6|*hSAGhIVX<%O3%`L4r&zx3m$KD>&`QBhnn)vazpIz_M7W;*o+x%0*y>scU zZnX5&Fnz=M!sT`|Qk0gonArH5D{!<>J3oh@+i=Y5V1ABzvAw-Vq|%Aw)(C@=lo{3< zrON1>gEW(g*$!<(j-tY6FA#FvsvYQQI35ZG@$RHK9t#mGKSr>dDP9TqHxtZ<(J|q~ z%o&hDAt*vt4+qc$;eF1~1xggHQt>o+G<*&yar44h>Lec}Wm&lZw27!!A)jOginx;2 zC7nkZX6Z4P7LAg%Z9e;!H2!M$Ki8tw5@3Uwvk@9m}cAkF~e=Ief8ViG)wj) z`ZV=@`elh=iY4?$fMHfcA!!xR?xAu_9VL3{0XgW43I-@~Ii0yT$H{d$#}WZtgog~` zMxOCY@p(ugge>ZQV4_QbctRV~D1@SbaT;c5&LGK?gjdJ%y-*5|iq6I2XsGCv`VlC! zJC1A}xI!Yh*z$<7AUhf1>+@#BQw(+R`B*6dHCH}T4b&VcZDGRfLpq6;Ao{F*OXp3z zcA?_@sXF78??G1`j_^jBEoqzMk;95;^8BRPy2muF_Z)?ff*M7$^}l}7X4`D9e#@7c z{qOmo$(-4@!$WiERJbS^mkHpBwhH1-3oLG4t%`E`%U5kG-MtULkH!wO^$a?VmHv~; z9tNf$6FrkWi^-QrSv%VeL6R3%1a=@6%Pn4a)CNZ+ciaoIoH4(QNP; zT*!zD<+V7UiJEo#RZ4dp=cCmrf`e3~)$%@8D;qC~+~~h}%IC4w3zs%l)0J4KVzgNM zc=flyP(W~ZnC#lV==W7$S*zxF?6h{{0yW=DY-PqY7?rF`$)>0I`qkpZ&ew3G_PT2L zk2W<)?ezzCquJ&3#_5di*0v`klG!Q!c`vVzwwE&@3ZMkgxlQJiF(wAVlhmNm2!j+n z<0T#*C#iLMws4lxa&Bl?4&-7VS?qYcm00nST zfDsU|+6RfhlvrZK0Dq&AMnv(&K-#BGJV<4#0~6#hsxHOIfGds`u?i>+((<4;5$iD$ zgs~c(QNT0{+9qS!a63leo1G=>{5sf+;^e%ZsuXdURi??nv@6W9-bf!OS8R#pI)S*+uW6`aO*RbAK~sTY}W8}@?6V(<}_F^ zJnSoa)>~VkW=uc4|9-mEA9r#5No$GWYSyNq!S;oib%*>`gW;eI4Dld-0`ga7;D1e*Z% z!)4Sf4|{antm=Sa?`|5&e^Ly+?ZbkyszHanxb%4E8;$6c`Oa%CB9vp|p;f(`+>~2(NXVynf}?Q@P0B7HdXj zbKW3I`y20{=6c%n)~md^U-GbUu zr7a*?<0epm9EXjsH+WlZ5qKG+vj)o4;Q&wxqU4#B>BCTbGaOkarL=%3p; zxs9WtVj?3`r--2iAnAGr+hKp#{kPD700V^6+W7e(CfDnS2}=cXVv@lM3x;B-ir_Wo zh}M;ezl!>!y%%dQyUL&?{a5U*Kvk)ov|481|0c3tmI8nQ(YCFt1%jdb4@!u$b-4^9 z%WT}$t(8!)33WWJtOI!oW-h8wP!_?&NzO7-i8O*h0RYPZct}SGj31=2xX*}6o-UXY zDMoCakX4JyB-E`=40x3Oqqa58*-+ce>h^~hQ&qOjdvl1}dEVADk9!%<>XJ_x>?y5G z#`~HcH*HfD({<;KZT)Y>&LzKuHK5rm*wzxoCKzRU&>f*^0_wGR0VUO`baT(_1eVX28Pm~mjDHYw&g}s zRsM}mL902hvy2+dX=%G~)4KXVOnzR^39`!3%B=+g7(a*k)=X2S_%8q+6(JrNCFI0f zB#;a?QbgdSVp6<)1xTx2e@_kbr8_5PW!wF|ajTT9vE^;nT~{%;g!<}k#d_Wh@N)k3 z&25-A)nZnCW$b-k6uR*xg}ui1&i881crx31quAKp;_5Iq3Yig$fYW-f-$Rp2bqD|Z z;so7?X6jzlD>!>_+iZH9V-Id2IhRNcXD!4`HK@Uy<+uYh(ajsea7HKyat2oarAPz% zVYBl91<*=F?_v(CH&4{hZSakzEHLM|49#l~1Z)7UKx3UW3sBKuRcj7MlAx#2;Gj#4 z_btFk4IMsGq8nBh0ih*AQV@)iNzoi+@xsN6 zEGt=#Vo@{&_FL+%nj$h3)OpyXP5p6X4GN?!{EEy+qSUjprgZO2)t-{Wve^Svlu9Dc zUvEtbwq%dJ1uGgWD4B@^+Ado-4-TfdcCmoCY$wf8kvp04+-Fs)M8Y3%(zwRe5q z`JGPZdfw>&xZz&4zpu-?0f5#UBmqOjC=w~*Dg~W#H8qrL{c$lN%r63?iQE#ZVgQjV z0TK-QN-SDU5cvVwfggnFY%utRwtm;vZ7Lm?@}W#|;7E@(h=0@ZLChdp*f`V_Eih0J zssLKS&aVhPpcct-v=I?WCb|_teWS26BB9C**Ct?#!3hTprbZZ4uxbENjT8dl7-EGB zQ!qi~$q5z_5MHx1!eN?<{{tM^V6+A`)tI>2gniX!uOj21n^=(Rg!)Ax>DbiPGjmSU z?-YPuNBX?<4C+Hs{l7Estkbn^l{<6vvzBSCQD=lodRr-#{&Gp_Y-XnH#HOmu_TCv@ zjM&C{tadXoGcBI0hj-0qk8q{>_xDHqyJo)k%DttlhF$;5J3ANx78>c)40}m6w0f0g zbzdd~8fD7{BVK2~!3@cA%TeJ-2PBk7F4Zm;8B+v4S_@4y7ICObGj&eZk{hOQ$O400 z&uS~Rmb}hdLgo+&Oi<#qL;^NUy%01y*%gWVcajFP@Lv!ql|dq4QKh7)k{MHQEP$|( zZLX=P1TB1s4aK>Kh(thg%zp|HgaH|1=?uyfsnb(N48?^4?b1@tzLNV7+^PV%HvUxO z^7l2Uerl&Mir$q!3vPBe@xgHQXPQ4Me`VBnTJ?QYmcx@(t4r>Fr=gnw8K8tXxf`U|5A&9 z0fB~&Ehh+S%%o89D9R#$AhOlApd?aUm2G4$5^kgEtTI=wmgeLrbVxuVYF=5UgyrZj z8#zFwYh93-QYyUxi9{dP43!L7syG?re(p$pnXmlMx&l;I|yc4i(Zag)9ArpWy{7U9R%7Z;~+A&Z$< zh_v@|1CqT{FOAzS^fzivetsb9K^Ni_)RYs^ivLnS*)4hA)U#&YUUJr4!mbtdetQZ$ zHH_!~`{D%a5BLRUQ3H6xaQG~`Fl#t&9+7oK4dX4t-ZJQcyydwp*X}oWmVL+arQUnT z4OjcWR~>Ua?KmnC&5wCdF0vxq$f1WA!x6KZ8su;)GLrbdjv`XU^W_=K~U8Wd{_N34EBz)SYdSL7&96MUvww=MhZV14oxO>C);zlE%Khm3u;w2Mrm3)v-^q z)P`8ADKuTmW^f|`G909uEfTmfbspMAfcex+fuE%$)|zwI0yODEWo#@`JrB*jcI!qW zamjrIrZ-0D=Pa9sY}30vi&vDx(%UhY)`FH3W+L!sotv`TknJ>Q>_anjSGOFkZ*=m> z9#`WO|5~nm*Yfw_Qjb<|-LZwcSX15R8Gm(ixOVN{fB$QGLUvSO{{M+S{FNmDFx=w= zhdQt^YoQ33C`^DDFac;895C`oFgPk0rGSwEhO8;-TjxkkETN93D$8}ir6n+MK~Dn~ zMGm%7>Y-CUV5#(lQXr{a^lw8qBIHT8gVdo%SYr@ap+K#I2)Sy?qv(R5$zB!$E-EI7 z^a4XhnYu>4VHy!obr2|yu^@rMB!Wb+OqE&Jy1rO6E}g+{(#gkS293UO%pEFqS)U*4 zF!f2Q8}~a5#iJCB$)U=jGP)=xBL_$3FV0nsUz*BAD6>Zq&Sou@>l7b9$J)#_Dw~*? zr<6%6)w8|pa{OybW+n9bW6CQ0&v@SE`-Z!|W1r`ac;Q>I1u#=cq?6`%{@Njp(-@&a z*Mu6#5rc)50!4&UIpi2DLdMShn3yymOs*54!$OBYeNRPSz+e!bmy1BWC8#dx9aEvo zlfXs&YKtx(My8H|jlhY>2U#&h$8Vl{?Pzpv^C?llu;2EQs<4$VfDpk1O$e$6d|mVj zEJ(Vyn1%}Qw_^gkNuW|11co@_s%E`TyM7;SnmZtOZ^2b!Q7Cp<*D}1ONjm*eOvda^ z_i=X$Ee$Yu7~9HV3GmD4-5W3lEP_=?yF4_vp(~(U}LYP5f?u#gR)+m4~d>b&p0LXqC zKpF-Vt+5jOM%{P%Ec>}IP7b?KX{~Bn{z0$Qq0GAMy7I{D*H#atj@Xnyb!9Obh;{Uo z%U&qlF(H;vMPOM)YV>h#;~tN4Be(W`pHixyx+%;fQ!?mwKg^%~|a zJ6?)G@)rgZ7?Z0*S!Yt()#2%EhD_j4+^Y=kS6VwsVuq5f+DCR;^1;r<9OJ7Ph{Pil zRk4=BqVm1WPgRTKjY(ZeY+`Z$h)i;xAC==BeUR5_n-F*p+OhVN7T&Al)q)p6V@=m zRcMiD#9B404iX8OfKw`Om!ix%j1hn%MGz2t93oGw0>icuArzz_G(%r81rAX5=z-|? zz}y=0B(PTHwwdn3a$V_!L1rzP@&8DqrVB}^Td zLyp8S`cJ!XsdW|l^wNq7X;iV=bfNi7Mq&P?n~>F{wK1w1wqvuh+F3oSX>=+2zgnKO z-lf)Yw^owCg&Kwl zMj|K`$T&r`wql_SHcd5(h-!(DN|lrq3O$Pewe1P)qe=v;O@it#>Z!;eVwNI;0@J-` zjUc$|C3qL16xSH2islmLHHLbNh*~lT36aSMgE2&I4?4p?tI`c}9@;8MrRE;vzR%}l zKNFkedAP}|R1m}et%lRqNTca{z!Q^(YuB4~>yz|E|CvcyS6~QSXzjZJ1+eo1d9sdCskb78npQFxZF* zk%$t8jh!@^3>HHoEttlP=Cd^*F#`zxmZ@ngNYwh!pi%0KJ<%?S;cP@6jQXP`GGB%3E8;Ffw{{(3=Ak1VB*4ILbV{z zQw$(=dW)zt1>{gxm<1C`bW%llu(3xp;Jd?sg(3zov`%(IDAra5u@;~NWfCS*Hx_hw zD-0n>T|p0f3+ukhM#>OWuW!?6zj=+9>*)wnTbKWX)i15Fi290-*q@@Y+GB z+}7l5>HLSA9jI~vjy#C>3^})_C6xbuF+~qfZdXlznZ>zhDwb?&tgkAPx;d&_T;1$5 z!k*0qHN3A?!dGUFljo#)x>ONa`#g}!666 zl{%7#?e!N`$U=;;)m?R9=7ONIbB+}5);#IVkY-9*w7W1Xk+8s%Sjb3FfK^d+wn>`J zBBjHclca*Ke{BWeKzJB1#79bk`L(nIpkh^`TezdiXA4bBz;c*S zXQ>fLLLiMoR-CPXq?}RFO6C5wS(0%p#(wlP5aghGIs%;eJFt6QYmS#9aMZezmYNke z9;1s-->;lrq-pi5Zc&bM*-Z_L)by9?)s{%$K%31r>cbz9`rzKmf3b|66GZvLk z?ry9LODLtiKP`QGjJ6uDT2rfd%eTu|+Rr<`|67)8{rtC&bIc}dF$(W2c0i< z=^b?fs!j5AJ8!W_F8QTQ8Onj#1RHQswu6XF(-bjWNu0=q5?BCg0yi-b(A&KN+k?>H z+pLnzqyjh=%oP%`r!cBjStW`J7?R(P+$d0}m%0##0Y*@%BwQjhDM~dfN~BLjG+?R5 zjSHl*CD?0$fUEp$%NL%LJjik0W&&@p+9lOjq?&Kkf_4`@a}l zgC=I=m*40b<9m9e&nUZIMKz76yq3IXlH9&CJDutq*?l!E8DcF>a@5yy)HN=beR{gi z)Rs|ptkwC8UuxfR?c22d%a{NA;sooD_y}rHgIL3G`fT~&Zy0VLRjWJ=s^Qi1x|wl zK(M9}D%e1XP*R`<7zo7KP{f!~WMS!b19M&QrEOTOjgY@-I)*JJrYn2`%0y@sz?K-y z3UWd$jH5s~nU40twFLm%Zb=)C2YRjP;@ck=Ihm(JKy$oTJvBchnrEwWN=w3MSSj*B z%xMHE9B45zRTDs{YH6x9z`j{9$SX`p6jB2MB${ZbyUGwLZL6cw%6}#5qXDLx6IoJY zz-ob+DT-DjGd=*Bmn@|&SXV(?Sd!VXM@vfR#v#cI&1Pml6`i4$K{auN$G!remEWD9 z&mLu!xvaTMLtTtQ5aT^(qk)%&74;5D3{xW5rWtzhT#j4Bl#VOE0zj{_!Zn8`Umy)~DZ0K~FQ;L1jYX6bm@K*3V10)dr5O_gm&;6Rm;Bb_GwGU3=A zQ8kBdTJ63pz0*fUaSzH`Ysk@<0~&i{6p;U4S$$YtJ71Sqj90B{FLr|%omq(mCKq>| z*-iTQr|VAM+|9jGODW=6%Co6WytUl_```rZkN6;D&I6glaQ1AOz;ifmA1!G(4rdL- z5;CU&yy3Vx+%xCf-{Y2f+s`~Zm29{A=O*X(|M~a-`~Us_|NTfa3&_aHqXvP@&dELO zG{Q!+5e^Jw6)?aU!-2&G3kQ}IkOpEPD_Bh>_G6M~IF3Z6mcWQ%Z_;dNMX+ijrhx}O zU;t1IW|CA0MVV-USc0ZP;HhAyQ1rnu3P*tw7-=+CFF?Tp-wLJ-47}z;Aw$54F9r`k zOr|Ue98&}yLlbahG=v!pO0!z@_%ARq6IURI1w=D~IGHg*5teDbJ?WlMj8hq~ zRZ47?Wt~Me^f;j5klR#v!ObH{q=1bg?=#bhQ4lBr3JyXdx7J9eq6{oTBBffPgI94e zAiQloUZaBcNG4*1VuKz!Oz2X1+*Z=?hUCaK;7>a5U3>n+W$PpQ3Nth0RLCieB9BL3m z2^t0hg~5!xgf0MKU<}C-$)_*+0E{BVjYKwb8Y@}`0_323uC2)q^|=QcFKTN}oi+V)9-S^&{x8W8zq>P%z@+@v3NVCA3znJ=Sl%$BV4ZpY53W)^VJ@hi~<* z{Ad52fB(ydtIqpvm=y#WWMXN=!J(5Td5M_NW?^8EaTOX&Rvj@h5W*ls8-+kZ@Mx)_ zG=^lF1~H)|v&E}YAl({bG#7;1000G!Ng+5LC=F6@1O%c4oDk_ zo(8ClU~08Cl)e-!ct{9qN*oS3YZ!nm0KylQR;?5RrCJ2sW>~Q%P{=}3sf%*vDZ*JN z^~e%lfaisTGKQ}0Lpp&S*1GyPjs05ml^;gGVku@70zVWRj8f7~Ly=gmA0u_{Nbk&A zzZ;NKYahcIy=zn(uZCZ|`_Jb8`{D%X5BHE|P6K&+aQJMgz;hUGAa!dr z4rdL-2r_2Dyy3VtG2i#|?()}ixqrL={6G8uzyJUL%KvEpRYIasED5fSrg35%To7WR z=qU_LHZg!S!XxoRI5=Jyaxi#SR746uWBV5liz2q+Z7ix-5-OtY@xlW2_K zsw{NKIJri6%7m5mesHLIB7nt~Lg|K@W0>ZJesC0rCThPR zHVD^d?n@f<5pLvC8jQ%_*g5KpQpPzVjYOjG9BN+=%5FwsiTeUNdsb#Bl^>0@E z^5(UwyvDEof2&{mm+SJ%*Z#Y`b6?N@|NsB|Z4re(rHzwFgDbNEs-rRX&*D=wC~U>S zBMN~50K*6Zj1GYgErb;Zf?_ZSPT-P&!U(d7HbGbz5MfQg4Y(8lG)Co#%5n}IA-p&O zMA`th7pNU#V7dtw6g3ykkbp@8t0s0zjq^)T$OR)x0YZf-cFXpMGW8P#G(mRD?4@j^ z!W}~q=>Sfe`Y^q7rAR@=gzmHCt9Mg1LWCiB*c<$+3-K=8NtvC*o zlAP_d6&!UWkr%p>4st5PP>ZyYh<@Zb$=LJHZq zRE66h9O-z}z4%vYmb%nbdJ1N)9%So)m5qW$XCao(s&Dlx_YXE2)a;@fhFV;y_M+T* zR?DZK$Z_e;GnB`}^VFAbz|{2BXD8u_T+LsrYM->6|NG(u=#TgPWX*$_!*KcxnZR#Y zZXX$wI1XnG!`U*Y0nFjJq_w;!?bX#j9OayF!w&xS-`*SkSGC=K@aO-3zyJTg{r~^- zc0c`#N~@Rw8ffA9kp-r~h8T!^W#QR~0mPs%2_Oh#F?dkIfnwDL0Rbl)sKph4AaNkr zGBu%+2$Hm1SlMKZqEZBTP~pJ^7-13u7?}Y@ln@3AJUM`H;TDL19z56(9h$c^m4+&S zm1syN4R!$mEsBa#s;Wh&7?9Bf^K9VdBf>qXn!_PIg1`bJrZOt2OIJWD=17&N0;nGw zGIK_s=D_H|oQvgU`Du>jxAvaPXyjokb0Y1$)md}-70y*CuM*D0Gr9@C?OAr}*S|H+ z-{spI?pb|WxZ%xZf4k*QYY+Wzz1F*Pxqtm9fBCP^zpwxO|NsBheV_D~Wh5Zc8m!rY z69fs5CT0>l81S+b5hH1XMd^-X009s%Xk=jUdMKU7H&uGH3*M{4N>;(FI@;m9<|$Vn>%$C{8*bNaSci!cfVESt)c7Q1Of~XeQM|!v$T6!h@{o z8ra&qE)z*)$%ZI4yD)+j2Bgyzz7A+%)P#+YGWJ-nl+A%I2cd7bNgG9rM=9gcTP_5m z38A%1DT!R;{hT!z99?Bx6kiwKU3yt+sU=;yVQElQx=~t6y1QFhy1P?Ax+JB$yHh|q zq(w>uUjFa>F!Oot{mnCH&UqrlLgN)Ir6QxBbH(2uEM)P4SsnZrj z@O=4ZV0ueMm+hsSbIY16V~+2$YO3TL6IPNRWJW=oyfw4kj;V9Im0HmZ?C!3y|#0b zUdDT&YCg!BW`Yv#1!UD=P+q5M<}|DI@hv09LS^IUf=i4+LWGW=K!OMge320q?x=`LNhzd=@B9u)Kqy56ib&5W zjfR3^vCtxNSth;)e=*%K)MTGTg%ADZvqk4MqYaS82d@nSmU&sVgnXN&nnVeSplJBP zfFK~PxTw6l9-v9V-BMX9^rhV4?~~T`wCcU1S@} zwWlZ<-v1@9-Y!>E7qrE5dpx@DZ1Kvit|sO_F@4zdO*36XZPZ*1HyxfX|J_ANb90pfJLAxW*ODyABl>9h;=|L2HKEHTQ64D_pPnW=C;oe{{=aii z*M+kUCHHdN5=mFb)u)&3{~BR6Z`pVM(F*QaH3vuQ4^+ndJ}%Cv)A{Zm%u-PDg`hM8 zD?{!ggoiLD1e}(C*GNnjA(q0M_L3zb4G;*C#GH_oO;9}0gAvU}X(-R)0=}6q8M6}^ z8Nz$%G+D_Bxc{J}qHzB);d0`^C!j%WqL8o&6dP@!yrAWv>BEJsbn%JAQ)*SWJ1DDj zf|&6oTt%d~@nJ|&O6gofB*Xr@eY&I`nHs(%GJuVwC<6*d?HiJ1(a4b>6>c|)YK{gr zcu-`8)*F%T`G58>DGiucYA=UR0kmALM%cV|g33SZ`{^>#y1?HBN1gkzdX86B1v%i* za#gK~im#_@M;EbORqE2Z#yNx#o{+Rvdc^EFaBNm_!Xo>r*XyV=2j=3`LMk3w+r~Z5 zaCpS)68BL0rf#sk+4_oDK;Z3{{~-E#ojvbt`%~x@QKM3`S)0S|_#q-}e(5Z#e$eDi>Y9{{yG;;0NDp~-+7`g5?0c(6YWBUqLIe%`|$3F34P z45OniXpdyk4FEG%Vj0cxH<&BZks+MT>OM#U`{$g5*MOqWW{zeQzE|=qF7R+pj0`uI z_VO7-WA-TCnEhCKfCPK^4_BI-d?{5>dWgY7&tYpEkvZFE_mmxLV}mdA0~rmGw=+L8 zk{?TnOQ|c=Rm)kwi%eAq)g*}6u)N;~F`NKWK zQwy)2*~wK+D*2sFKLwk*DCDD)XDo|U5Lay=r>1AAXH0}p{RavW01TkzOsowY^@n1F z(TO1-lO|c3<5@Tz$zBp%(cVOy8ymdFArDWs4bZ5MpC~W+Hmrij(krhlY@+=+Q<{#< z?Zwa!f1FXBW8A-e9@fdu@?X{LPqdEhSs&{>lZbWxR0Vv&Ib|AAs6BLRjy8EeI(J>@ zHEZ<%?yec7PW2Uw75{0`3E}^o;i~cghcpc&V_br|NvcLi7qZdWd3I0% z1gYxm-53fxd7FI!5{8D}FMLy*mC;Q>G@LB@Cd9_Uv-M!wCtJzFa`HT&)n$)p zq1`NyM;X7hfWuGbS(JB8AR?aU_`MjgG5>y!cqFS-N<2I;fSeEHT}foNKn2st7o)lU z4t9mYhVUSstlGXG*px(H-bkW<59Swmh@Grq|EwQ6(Em;^49AP9Kg}e~9lFwv@ZdU^N=4f8=+AMzHa| zr&hGat()f!E*>f?hhi!mrG z=DnlsMrA|PY)liJYmmmPl{=+3XGlmVrU9aeXmRXHoxhNYw)XGG7Z!w@lsFp{B{ftb z3OQA7<|m7E!i&aJGDbzscy+9eC{;=LYD*QriX_VrptD;8X1v#iZcdTS~@bSwF<^S5AG)Fd(6WYe6|3IN9<_1N3DpLEI z(1WSs_!kk~(rZ#bF4exa{?k1y=mEL?`unzoXcz>89&$^esHx6~irVJ` zvAY1`i5Q_NJQvQ~j+hWVP(vK+{OxI&I*;o+)L~rXT*)1V<}%whR5QMI$_Q}FQW(2R zecL<^%EyKllZW1ktEl0tY`?arN0;;)uE#=+ z#0ce#aI8wzG<>H#04&WZG%yyAa~tEm#JRE~EO&HdOcGgvfr>u0h}w_p2m%3EG8xg{ zaBp(>@AF`yMj+CKmiRjmG1ySXskzZHu;V|-2BzUQO&2;N3A-~%Z9Kea4G24mW3}?Z zkVDgaom-##QwT+Lsq ztH<9zS|8V{p)8c^^sPhh=a!AWc$qgSh>Sv<&(0vt$rXMO&L6#3tA0NJ?rx9L9`8pT z|EW^7&DLJ(o!41@SbsXrq63hQF}_AvA8#|{0*HD=p}A40D5%J8rs^(nc#-1)>O8%d z8h2MepbG{h09nG!(hRAsH=NPO11eYn2y^^WJ@O_`3$W~%de``f>3Xe;TuJ7pa=7F255QLFRTE&qYSb7oxrvu&$a zuM198_{Q__f%?Qsgt!ffa>`R2&=3b0b*~=1bI`s_`*HuX!|&1{_VMEBY+ir?XrLZF zR}Iw-EidWql2qU0;xs!5>G^J9#^?!xbtLwPhG0T!qcEvHM+8=?y};1OQ;t#K!({Sym3Y)=zd`x)@)2=4FTL0%ZEy66& zC}O>`swcWMP_QQ#c2P4^g$J-sNq_W}WR7H4kUhNA2sKk2gW&Zqh62<-wDmAGGp<(xwj5B z_6wV6{%HC%(SZaa`)8c@agjx!%f4#JT$y$vP7PU-fHgVt}pen zS_fpJa=htTVy{Oq4NdcgHg>9!#3f~eq*BS;?<~VD(@mFnd$R}ydO47#Kx>T9ce4QX znGZm`aC}jDkx)vHikAcu71U@J?~G-OhhT77S#0Jsf1W?zE)lNi-(9~eXkkGV9NX75 ztjV!}0ki>m74tX|&3GUzct4*-{D&+#0({f%Q0C>C9+@5r1UUVIFxXlhuvft&tCIzhR?z{-VF(kxNB_A3vI5 zg|-)?!Z+NiTQlPuPZwOB#xIYQb&XC-ek`U5=G+D5n8KudRM09Ohh2^kRbHr-=fc%vJLii=CijYwp{=VeBxLgsdd6H;2i z^jzhcl+6JIK{mni0%hdv5LwC#a%n>`3zRPc=1|l6uCCrNGCkBS+-!z)OmuQu#2kxd zG$j$S68`7k<0xm6v~gg64QC^N@up#{G%fM#Z?0|_)K)PxW;pTHY5#%32@*UIr;7gE zQwUTABgS_Cl-hNgR9OHNyH*?0>T`h64hclM`e3s=Ow1=QnO9~&a*YuQY}<&Jz{3?1 zg@&fW@r7nooOk?DjiSw#V)|bUtD)-Kz1G-d{+zS}zz>PsZ5Jc(VYnvS!XVX;3gRnm zU02v_)c;c@SQgn&LH1IBd%>5F(w`?UEF!W#$QvCtt;1u>ptrp=|2svofA@x6;?9{x zf;6iYr_q(5oO+H<}VdTZ7Cd|oeyJ1BE$PU2d(oHZsosz^q5Uz2&w6#5V5hc(dajd10_wIqeuYa^9cH|$sr#OrJU2+r z%EYJ9g_%0VUYn!Nz8w;hQEBz4ys!WLmziAF!)RMg>JfIjK`-t@=GDpeWb*ruC%$IH zZyF;0Ot&W2m9BI;SIUucnEYzmpL8HX2)xE1SsHDr8uA>NuKH{@@2+NdPG zsOOyvm>WV-c+H7YQy|(_vg}a7#ZOnp9WLsc>{jWBi`w(_qHwK8s?%<*nNhUujL}s( z3O&Dwon4U6Fa@|mJOL%!B9f2g=zS-N-K3t0z}lJZ*86XYHa?RB8`#Yrwg1lkRK6S2 zNX8_9)qLFtLJtBz(@(1(wA+jgp7T_BK$4URe^r`)Axiy z%_6U4et9Cor$2G_jp4?~yPC)Ld7b}Bb2H`RIAWavZYv0DgaI!g-{JhmX**itP`Svz55Nmx=XDTJwvq-q8&TrYH6*OXTg>=?)fp zpcLN|2e1H0C+KUhebtWLJRhz0!YgxbGI>`KC+YX;A^G(qeKqO?3ecRejo_wY%J)lh z+bk8UZ$%Sc#$C}g=_K&}`6?U~CK(C+3yf=Go9~_a_R>g0e`m-nXE4%fJy7C5P)Lit zezH|Zd2iylc`6@gc5F}HUH7bh-Iue{~h$h2C`5RcHDod>O!Cp-7iDckWl5cSW}e1X$~Xc_AL}}Zuru8 z=Bu=7V$4{fF%`cxK6eF8Pq!it82X?K|5tDO;>WPm~`O^sZ+H|$Xy9fsMGAjT}Eg{m4!>N)%x}-(7^E0`5oymH09z6x5!F@8I2fH5N4^e z|5z9cosN5`2o*+nq8L74R;nh#;kaEVYT0#pDQU9SsxT3!SX9^&ohyj}D|7u8D!nxV z8y(r1kV4_=fDWX`cmmlwc_iv=mTt#9>JI;5Qvdp(*cdV{ zk~p%gC{$f%(w*=+_AtxM^WM4OuWjuYhx(^(vmB8QOKuiY5@(+*O?Jyae!9A6d$>$) z|8bXo;N4)D%>;V-IIc(iGPJ<6H*9Z}#MwOQ6Z}sPwb@h@uVcm3p`_6n6=cpnkU3^O zw~fORMwEP9>H% z0Ck-FIn-*JKrFa)&pQle3^-f=)GZ&hzZxBLcS&)Q)-@DA-`kOcn}kj|ScQx7Lc9U| z!HVvSx($u$0&9&6sqI2ER;M)+G4MfaY%+&ql5KhC>*ZueBss-_P`D3w+b421h@4K| zd~?glsD|St@k0&ucOOCoeIyCnQpTldW%m1xMY4f!5ocRX_c@~uF9Dy%b_}LdW)Vtg zyjclp^W6Sq#oY}|Xku#Jeh^G#$e1b1Is*>27W1saPFGeB4Fpz~Qm4KqqEdn8GbCbo ztr&#~t}7hY0^_QS#isQV4gh5l#>yYKZ5Bo>dMk6CHZfj?|A`qwL|}d1LkFbUtMapX zsxzBr4ZF|IP$e@PfBJUrv^fg?S39+Z zuTbU!p8C;p(0aMjf1aPByfljQiI^xyO{@%DJEDz4C1Sp(vD;W3t$BPBp;LQcZmnia zJ(*(ZlsgfS0ZiHyG_LU*IXbKraXgFUO;BlnVguR} z%5V)Mt?XNmXtp%YCAQy5eg~DkpYfmW2t)kf=9%PW`q<}5&2~a{8__-S$+KM7GaGZY zrGV$$$otDHp5{+W?ya-n2>rtB%C_TOZ#If=6}9b41JE=!?7Q^=8!~;0R)y5*U9s!h zK``V|!}+1YO-=1>tmCBb#2!V11^Z(|W|K|()6X{@F1G*VK4@pR-kq&x#ijvD&~m3k z@g&=NFpxBX-Hary*nm>khF!~A^MxL-d~p<=cWsgS|@Pfv?8 z^B2~PgDW)@w*-D22BZpqHyJ*zR;UaSz##W#{8cG)71;HMBe|9fvz=4pM^X!{64r>? z&3Ar^hg}IP>bM@=^?Ijjp};k-*IKTgF%sY*lDAw@^G!9xyU=RPdgyq*H0j~ww_54Q zcf@~%!eQ*qkeLdKSFiKKu{Hde`XZ_(>%#czsc@(ZwS$F zZeBmSik3tp0>=ls%vSA+!o@z!G)Ji%OibWrtN&4jBsEnS!qrzpx}y+c%z6-CHFn&|IPvzAbWX}cmm1$YFu@0-$Q@oZ*<3X{6-- zc{K47W;O4L57EQ?Yaf}mrtm2Zf~AbHOeP{_vpvZEnwQ20LAKmpQY{Fz_ZRWWjQ6K| zt(V{w*C*|n$_^cHdwwO+GHtbq-YzG$v)p(Q|283H6WSw{oDm)V>v`G`V%An1H!)Cn zQR@4zvn{5{QHgU`fRV96Z)ZULY0TW(gKN-5@S6?$lXvI)oSRbjU{q#eNQvI&G$jOA z!CC)Ue$#boB#I9dwAT)Nn!~X-MQ06P)og*l@@Y{}@Q3KM3{AxZH8<7eNSU#r;u!fQeGz%Z|)=@=I%3`R~w~7QT6(nx&i{_e%i={#sc*A`<4Q zPh5dWB1~OrEQW@Fn%RqV^h69_GW5D?Rn*vD#}SWBZjU$pE;ctUU(PhzV$2!lHnXpXC zkU?4}fQz3I`Aw<~e;GeeGIa!2=o}=)bM4G5zn~}kxmz(la>u|mmh07HmR!J(VsYbd zDM6JZdg(ytx223@shLGm3*wldUFikP0PZ4QOLeC^T}W`3QHqwld8-{`zGVGh^Aj@v zpI-a}J!|V>eF5Ie|0K<3SUBjdKO2McCV0J#Gtdjd_b)FF@vM7=KBQ<3Zv18aIBLPv z_=De0|D<{3zS4%%#{Hr_3&{VcDBrrNYO&_Q_`6_{uSA{J)6oWwq8)R_TRIDf*XFOS z+40-GT%d7L87(fpMJVArRI&w?d60?|Q1*IEqpd$^T$DzfKGHROgcX%qC?MBgg_t=U zC=JQ=?1gOh&=mga(=!{g1j8=R!B4F4yb#U&`x6#rMfh9r!T^s|3 zLUG-DWcJ`ZOQ@1eC|zxfRFJSijz`UBFf+J@&}djzzE3 z^pXFozf@RiZOp-vWt^0$Pf5YAbg1N~c(#=k+Vtg3MqA-z*WmT}OM?4@e~ew!GWP2h zsP-$4%0iQTFr;xIGPm;g4N3xCIstIQOsxWw^|gOWjdvbHO-Tux)rzJ-k1Qj3W*Dok zp-bP0uCmKVM$i@t`1?A#b(|Cmt?|B&tY>ab5h5r_(mCDcJo9AhL1vml;~lm#ndYH#&BIF?NOxId6=|iX_$7jW!?cpjy4$f$6;uC^SL|zuDYU-K*eKX; zQx=(5i&u|m-q8+u_MXaL&ADxhBp=i3G^xLC&$zhpSx=e}jCxRNwRqtx z&?Q+MKZ;QMcgpAijkiPbT)#=@4I^M__ucDs9d84=J|W$9lykW~5hveHo?XksQ}Qth z-}4dUMJckkp=azwN<%SWfFevh2sFgZjwT$De+LW|wLRbzEmtvx0+dt&m>0kThGOO1 z_5>qNy%y2Ibublq(s zXUQ47i38hep$N$BHKQG3J?Kb{4=_-!8{ceGd_kz0FKLi$b;6tdYd58Dt5Uo&Og{Z1 zbsSwIePycdOrz5!^f@;y>(_-@)lZ2)@Qq)#+CsG(g`ePe2X@7yMX!cz1+TPA_aOo< z@NZ+wxNi<<yuB5E&<{b3*7X-pj~H z`SK+OIX7YtLJu`DWkb5E%@O4)28B;&vY`#iL5E2p%;X|WPT?R-eHNZgrKE=ET3vCAlRBx zj4DQB5w`?sBuRY0B5>oRhaFKTkOyb%j#Ii8#F+ScR5E3Y7-|Yg+xiY2rZ@O&fL?zQ z;+3{BGYl^4^Zrp%-zuQjR@o4A|5>E=-}cd~br+lcMdJE~pB3P}bqLk_N(1M;Y6zIL0>v%jd%Qq*Q}~ z<>vn_kU0Cp5P9OHIxf(LWb6;hp z)@k!TTK_UGDn<)4N`I;NJ<+g%CKsppE;I!w@{{1%Gue@)8_sfmL_t7)NVfnt# z1lNfc>6m<=qR{T}M=u#!$HST&j|6hifUK4f=nPF=CE!P?6;Of`zXw|sg!!y+P3>0R zFy`{#tO1>r#~~SdJQIScL0ifQOKnjCTRFVDsGeE#;oL(GvIe_hh^=X?mio*uh8vttos>zoCO&^s z*Lj!9eMerO(TweJQh~&+8Izxzf7nzZlwNLai?8|{_7ipI9WGi{{?5JL7Am~5^F0!{ zZJhtQArGclLwS>IFQtkQ4o}Vs55XZWu4^(LlhYj5Xb-74CxCY4qa2YZ2|B}PcnAr? zrSHSmpON1tdQEtt#>;3Rt1Ob6W9lPOn$Xo;6@(y|c4^o*{vw6ltTyVG^GV-QJ_wqv zl_({aeTCFr1DHid$_wj<)TW%DaO^j9DbhIL{Z1(87R^=H^UpkRRrNLa_&qCP&#j=R z_OMjz$LC^+bb>!#KMa@}i|d+SoB4t086++5CRntp51V+6bAAfWf8O|{dHaQ=c$H&V z&qAl-)vRE!&OYMJH$LW$#X`n@}diM2(XUkx0syN-?@7(6On zpI$HP`p?j-L7h#j#`Kf7ng^w~4-9+9-;iPidSXqp{bGx;iBJbx9vF!E}#8%8~`aLSQ4nE~= zt$rT_1r0F~s{et)Gt0TnWBR$J;C%Z_2j4+RU;i#%{8>2NM^tI?pY$ORdv{(lEyPL# z9pXV_<`B`yZzATKBV)tTsdI1e^yCP`H#~$yornDlRMaBiBZ`}^7HSg3Zy$A@lMPiD zR{iFt;!Jjg>{K>GXs~K!jga~p;bAF~)stI?6M?aOak>fU%Umrmc3`~np;1U_t)k-x zI)W3wy1n^QR(c=tJWQAuFFH{we1osShi58R9;1cAkVR*Wh&sbnt19xF_G8p*{NAv? zeER~TYveASnrtj?JG^ex;8>#IJLI$Py7K+Q^YkshmGEc~yOFDtUxF7qTE97KEcCSu zW5v?W_Y*V*>(q{kyOi4Aw)POdo4VG{g^LB)jr+~S_LrmfpO?O)Pu~CRTp0&*o3n*0?7$2nC%q0qIke=;jAtI6W4ZC zIjjbg5fKtNJ~l`R(l!qg7YKpn52^wpo$!^nB)jaM-7Ae4?s#XIaTq~px)+kJ>=|@u z6X>|%yN_}FxyrKo^fbzSD!AQ;?q8(13^}GP(WJpFaFtT|#S!{Y%^zWRRi;BoflgBv zeRhnBjxnkygDI4q*`?7}B{O8uJ-2j-e*(`Q4y{|JS8FvY_?kC7LvC^X6-_ytUzteV z)egJZ)92g~NdEVHLE}5kqMGE_x}^7|tJeD~cbobrtF^l%ezA`RIaLwC!}auJ@r0v! zmMryN(_|Lof0H$oZGd4+QG`^m8g(iCfP^s@RIMpaTL8Mk?|?4k4LglfgReo}9zoul zARg6xcc2!!R)8f6|FkcR9@lb%$X5nE0&lu2S6Lz8lxN6MQRz)|5l8J%Kvo*nj;V5& zGa3}P3}v(_CF~`D7S2%nPs!9gk;D8Sjyfu>VG)*rqYhT$v`&@+o6L34{lQhI2L#Se@S+!=6Zxr9f82U?UIKZNYapQV&#%1DvFn3jqwxC zMFdxfh)W@!bHGPrRF6g_X)p)y>9uP`k*xSZlHSQ&nj%E_5Non-aMB1W;)cdkiUePM zC+#EH91a5N8g}9Ft5hW%lv-an6aTGHEihK;>gE4)8dKziPkXov`OcSb{q9xB*;~h> z(G$D%5So-^^NJsT=PYx=54OK4K)U&yysr)q?|3N+Vt&j2onH2`)lF5jMoFB{Pt|L% zA^*Ej(=)#MX8u1=_=R`Vq4R99((Cx37y)?pU83Bz6DO_!pgcB}fEtiMlJeaczw(tm zFORlI8^5Q{h0e~Wr`E^buwPP}P}Fz)!_L^so+bgtnF&Z^#W*PDur)bPtYjZFtCQhh zL^Ku@^PUHx_`C&h%2^3d5WDOLxZfd<9)V?&m>>+q_ev2+M65v;7*HhjC_i7O6R+Gz zyjMPZs#ATW5lB+0LtxiR<8K%Rg9cKPZF}nXY%#NW9`P{dWLkmOR>YI(X)EOy8u34J zRpBMmlGhdAm59V_e+71(R%l;(mNGddNHTCUdG&gqb*9j{emAW@Z}H`r&rX@t%SxKn z%rAeX`QF5HVmtQd{j!JeLiNKXr%7~0?U~P-N828;M-EAo<41k&3E|)OC?HANTsoEB z89)a*`O6wqM$vBAG-IJU&B%Nh_pPXQjUi2t8N4e%714-g73K>yYx@yA_2QCN6v&NC zD?wns41tGHisnkkh4dDn=OL2A3AH8IA_tOQqn_!Km@#CaXVc0=X^8#`!>mBU$kfZC z^HjPdm?9u=5g-%#zj~$oNCqfo#+aSV6m+F-N&GJK2Y4VQpUpEXHW9;n6~meundYi} zZmKFovf4qBG|3-{PgQAt(dD%=5h6hxx_)PCPVLu7oSqkT+CP$PWpVoX^@7i&!54Pz zaubaM=aJLvwXH(PJ#$V_)AA!A9*Wx2)o0FLJ*+)a2tv~3p~I;SwskxNRK5aUli_j4(UDX0 z(Qbp;xJ`ZsN)(8ZsByxa5YFN1zFn9Skz?%eS$Uid$OKqa0z{(*LdO6T;Q)fEWUT;V z;mq=g^H~ByVtho6N)H16P8o)9T9ij+w%-JVP_x&e`vXPy*k$)hl^y+~&{B_O(}lkj zblTc}N@SS9ZqQ;#ovESC#bTzV=D2E8gcPX`O#J0tXn(VKIef1rGrjfs<8`C3e6;)t zu2q#kBV{~+jqCUuXTg?5J2OFJymI2`eG7^@SCytu%}TRfO9R{0P5;a*Ox*9)uzs#T zVK0x~=eVSOCJ|JNs`7-~M;${9<>M=92mI z$Jy-usNdaDnnS&dcdUfEb7srh4~^2=hF8$|(c&^SgUm7rAWbmAu)mI05X_gJi-qJT z3+s+91U5~$i}VMKB{_D9cgxd?7g?WbFd}H2^Td!5QGt|DvicI3;V?2Kh$UUwzZ?z| zhj{^RX}TzqM z_NY1k1BE|G><_WZ=njS`=J92K@neAAaH8VtEC8V&SLtXS@|ivpj7k$+ZmSGP<6%_h ztSkfJ0uYX9B7f5?$r7QcXgHX8$Z589dTJv$9?wz83dMVaZqQYFx#u+5Ovo#cxB_wR zs-a*uX{Jq?{%lR2gJE%ehQv3YRN+#aU)5HY?BEko$jEa!L!6?vp4}Bb|Exox}gvq|ZL$AL5LEVy+h=975TP_w;w}cVt8PdT!FvH_CEoanf$H zgJU_Ge-|!@TdbYad{OK#Vxg%>--?+GH2svgnapjzH&SO&dc4ky3iu8qzLPau{jocUX3}E0 z((~oR3RTMNTb^Rh`cIEWRf*&FGC)C0LLq_H2RYgz^VAzb)v@opR0%OoXwKN}Hwyy80vDf`{v*5J3n7r$JxG}izrT(mSmMG{nc+=T> zyT1N<@$zG{=A;AjQaPhFdut53=D6+)zt)1RFaU}Mu_Bkh1~0R1)HHU1@k~5C5i?KL zXm6xf2dC7suv@@~ARco;mYzMVb~DUyYlUORX%uY+{?doW2gTSf{0$*7p_+28=r&8e zJL{Mx1MgfU*WOQoc9`h}Cf37%6Ds>(ij>~>eZ;_?mCNiGA1B6iIPA?)Jqu<$GF~7V zNOsQCUCHcUM_bF*uNf?;E*~X~T-P?fPi{%bU=!e8FZ%p*d%~vCM@{4+<5XL()8O&? z<>2qu5FwinynEh{zZP#YC%$X%|6A9n>(%_N-P>bXH@Ut{x<+ z9Pb|*ztk2*uS7%8N9E<~pBz~nxk zUmoU)jgD41WEox8=`O4S0)C782uXhB5K~WrAPIsNdYI8M>jC4f(!{-8@TM>TmU=f< z5IB3{yn4hoWmFTN7OR!d189hE_A{KJK$}0|lg8hUVsh*FAcT5f6g}7^J?&kr!gU{m zVH={71x!B@OzoB|dA=t2yU>TY?B(&KN}pbT>*p*TZzo+hTMeJrJmoIl+njbKH-$DO zT0a(Rbx`hZydG|>KdA8Q?YkCrek-Isd*QdP<114sh~c$x_T^H~$Jd%Vf>Rya;6$z- z0N|}BrnSmTn?joG3&Hp>4}w^&w<~5ec(PRicF{a@^A*`cqw`7$`4Y_1yRMYoDKzra zA2Dk4%YmX-J)&JK&nDE^ITO*W)>5O^Y-#FTzkNmJ6cd$dPi%+VVh>3&N`H6RbdG9p zFVW%<&TCoGlcmeo>g6yE?`~chV>;7Rb0)_(exHXvO5Ij#>5*wz?+q;R^ap~ltyj%& zNgYC#MSP_C;sov&cn>r}2~`>`e@g~NOp;K05R!doD02*?y0i@+gr9T!RqY9(9tCgBlagd4&w zi#GBC;mMo!Q9`C<2oR{467;thgs4ptMg}kjgqB0SY5&Q;e95;+BI_bLU~)%NNE%<* zDV^L+j9izQHg1}`**Af-;0IO+B#<@YET;%hm#A+|yBRIv_Py&MTpD~uvo|7%vLox{U z9(sl{vRbChe|Si2G1U~k2}$fN1n&#WvO=N~cw~vuNn(EA8Uct9B=jVa_%_xLX(Ih4 zb#wcAMZr+MJU1zcLeoemlIidQSrrXn`KDr-fDL1iuX>RE7Lsa*Y34;aC;_i&!A;V>2(yf}xq^$Wa%pfnV z9Is2W!rtaTPL5;*QOaZR@z5yHJJhJHs6GXte;EXI5F!et8YAt;6&1^(L`0gciEaW5 zF_^?0OHoBz0^p(`#*GBDCG!!=Uxg+ph(1cVG`7Aq2jd7R8Ky@kECxtt$M29$H+w05 z>8v~~s$pfm@JfHUw&S#?r-J-Xbd9#jFn+{HW>jgcdx27==CMKS8tP7EddI@S4P~-S z>CgSYbNV@jN6u;Oibo@tU(-h(s^stg)c;&AlWV=(9rH=nN#A~N-pL>8xWD;xuQmIJ z-|E}DwaveidJ{(}qs~S1m8Z-oNr4{%#?gap&5*^Sam<`XJw>^>#8_lJoIELM2Z&tq zT0GV25M);cs#qpknlwp)@mF#uYwXpbU@@KmcJxZ5Eg^)`$O3!hwKgFmkVYjw-GuSH zCL)+-BUn{CtagB4;ImgDAO;R+UPG`DDYaG0xuPl0I6rc`sXrTgSAe$Q=*RWp=9&qy)x%05S9g_0T*ta|p|Bgfb{r zU`aNKu^a%FiXx?~Qd2=86#zi$ouI>M2XRPk=psBW2{fCmK#6Y&J>XAD;nHHZs0k={ zP8U|%$`T~CYyyiJt})10muzIcOAq1zM4?+!q9!mKVZe&;2p;jKcgRK68R=C_NVW{E zVx7vQ(xUB_wDK@}@Zq@0|v6q{V&bdR$ug7z@mznF(3F$Yy@62))j(iQgGN zBV*Ad6*(NC`srD7@XOcR8qJ}2xx+z@x5?vXolVjF70g))i`eP1Q;9ttn@pfXN(rY7 zb`m_{Cb=-8A=}@DqZriNC5nb!&=p2-+t;nU#;E8RHH+de#X=q&Kq_s*M`s2PM@mv+ zW^M%_SShRGP`}R^`2^}9R3*yPf-xmrzkGj|))K*(!Ldy-v=;n*Qi?p6a_LLwR?^94 zhngvhyDzWfHiDAzt;WQ?Dq=uXp2@v%@^pCmhy{r+7&S@qhQPfAZA>B%SscnaX6k$usE2cCaqO*U*9hTE>OQ$tPmtVmIhB* zYA$hQJiz~LU599*ho@2G4lzUhAvB5>{-t5t=9Uk zp3-w_OK3Ns{)uOqU?b**mon`+l>A zXGQIJiPDF?FCPcEeZUG{M&@(lhwb~5qv>l4It#GJtKgGu_ez6_eW^v0UzqJEi3dkm zN=0$~$Z$N4?E{hNcl-n>{v|B6=IHWA*Z@i`aX6(MigG`k^5!;yT`}hoxj7p+}o_v zGLQi9jx5i2cLH>-I^Ic%+U;$avPp1T5Hb)5V#yap<$-EJeo(;3=v(}H9N4fTLRORe z0vXBHYMO8P+yuK8KdHYc%bP5;8lWY?oOyw-*!&#bH?*XI{;vdyI-K1$PSofZx*R8O zGXrE0+tjo){##9m8Id;cddPfiunrT6 zbGH1Q=wg0x?_RI*IP(WlUio8#sY+@2273K8g^o0uDV^4uZF(s+gAJ)!}kIYlFHp0~%5#5nq=+$Y%VKq6=g~mqsfD=45h>kVDx5r6iQa z%?S5W(ijQ&EfcN4!g9fF&CFbZBC(cQ$FAvg)%d*%ffZ&a>AV=eRES;(8drSP?>xNl zU-&^xK8|pjKs@h!&E?eR1XEB3C5sDtS^%@XZ*b~1r&^0rB@ZJtwsx}C#z}MJ1~IuU z$4!uA;BV8KKX*ohB9SZQrgwfjbjbe{;TgL6od=yW>tDp8%C>pi3?@qG9!*CrZ598< z`e`%o&gr~nFK$KahTE4Nekdr!UeuTs zcP{bWxD565phv#Rt*A1g8`2k)gPP~>$14WYZ*#t(rGAFb-%Z2IRoD-C3yFLfl<#9K~$LnOC-65ctYRYg{eXE zLi0C%W2U)2d8;jGVyP=jQz4PYj5N_Ryh!QOHZ=~v|NI??RA9-&Mg;vBSpQBN=hPi+9xM<0wO(o66wtr@a7x8lb%`Q>KRdvN zAwz-qMI<{eD=Vpp?LaBZ%LYKhmMoPkxK2zarl)xehc|$*Wz(4gO9z~|fYB0?42qO7 zT+!i+Ni;;NY$n`{=;*0r*3c*;85>njRtm#deM7biWx+g@vU^_R$xjpfaEz|ZS_5t} zG3j5#*fVb<7yHWC86;AtR@Hrb3Cw&&Wts@D!m5 z{DS+Ep%=d+BXDx0`{r2*AdesVQZ114xS$l~zm3=P$uH~s6pre7Vb#7tDk)S>vMC`a zRsAu9CwLbp>7|=i%QgQyKE&O6=*|2qeYnQ<1-w^rg5%h~#znmEx!Go##SAOIm}e`Fs37!VGO!$s#k!UT(b?Ne`sg{SpZ zRHErv6I?G53wIIfvXB4XP9!iYU%-XU5VFueXDvOa#=ws=G_Op~`^lUHK43pk!jBKp zTVgGTTTT$OFGd8&XAnXP>=SRg(4=WxAtwfQuHlPfw=Ckq51n`u-BbxPot&v=tmuO~ zgvsV9XPYHO`DxLvEkf@_nHVko%6)TGK27P&n~w8&_#X*Xzt62|%Au;;sQ&_`Y=a_N zZCdKzpD1jbwACI3$;6m~iMvg#OR6bxp8+vpV|3WG{Mho?5bnHaW{fd7$s`_UTC2$= zN&^ho9pkF*Ey0lvLPwCR;smcS35)>()pRlOxN_kDFbE@13t#qf7Z3`RdIpnD1c(Eo zxt0ytWyFI*%R89l5@}>?KnyHN-~@I#V^Y+~oV}2PB}bO0REgpjh17~O;|kRzHoj!) z<3k;;9fYz(_;9A49Q}8)z>EX-Qm_B^o3ur6WO(XcWrf0&-+$-%tP|btvpy`WC->Ie zby9JdOmLuE3?7-^3%&Le(rL%Jp;ZmAww}`!zN?$+z=)GrY}mj#{WJ3_xSbi z@>l;B|5erYaIF-il9G_a*+{(T!bF%{NUZWX0-R_94wC!E8F-axQt_PxNZuP5gpgC; zc;>F@jqOZVNZfDk%)bw}0v@U39fp5J3({j8(beSf!;_Bzd<~-oKs&$INYIRhfM_Jt zPe}&C0dQub4%&#RKq+%Fben)sG?r3Xlkh1EOY>&!JCv$mMKqCOQ%i1f;x*qbzT^U* z1y5L$A;0zAFW(~jrVvIEZRF~;XsFa=2BC$^p0lF7u{L!JiS}ku{qlawmx_5IS$fW0 z76tv6p&YX+^JkOb?pUR*7dv{~MUrHFbSL7gQUbKCRaavG} za)(pCR&pcudMU%1kXL6L`yBmQuY?S_FbryHG4X2vrMbO7j&rmaa-mIz=zYf3>}m_a}fBZaSxX{XAvc(=M7-QPBDf=Q&TB`xt_ zYQ?8CrBgDdFY?A;SMHxEe2=?b)Kz&3PP>2bAAQ!BW|k3a41@5s^+L8 z@hvbJT@?zZ_Q)s!0!ho-$}Xp8`Ru9T?col~NNQTQZc!am0DwT~QQ_u8JHi2vjL;lv zHcBS3E^Qg+jMuwg{cQ(s3dOA? zeb5h{zZN3M{e(jG83KhDn`AH%Y7=bMK@A)49 zQq`o-N@r9j#F|*}ALAw%EG!Sy1pxibMIB*sUeL-Z-MY z;Zd@RsP4k4yw`q99%fnwnk;kDCCW-w9xzRd-W$Q_x$*7x?V(McdTYr~Px4)NOPh1) z=)Go9f7|l->y>1;{{^RSp5IPB*%Y2c0jtV(`(HiOo&7(W0+^KhAh0DKaQpJE`}X76 z#SfvH$H!K-hFq0=_%C5vY%r+~kqHp$9M3pnCJKN?^KrS^r?I8gC8VQ6V4quU?*04L z&CC_fb4)QwP4LANbO;L->DBOFr&3P@1pzY#f;DKbh)nwiX-~OjUiTqsgZr9T$^!Vq z3#Hptq{6joqM8qP?GuAl+*ZbZLKD??@-zvzaC zn7X{MRnW8i&ivag;mCq*-)wW=7^8(IXm5r+f;RFIaVk_ViCeg;WXDID)VKFuvwhHe zah+={Yx2HL-HhjrZzh$gw3xo|<9l!I%mXLwCV$b3KX3frjO#CRcT5O5gA2;rQCFiP zOFx?EnB;5oMn5}eY@?RQVu5JEXoNAds+>t|B)S)nIXM`Fo2PWqc|X-mf~=6lgxp!j zoXMPW=4%G?$SQtCfk7D@u=CO(#@&vN%rs~$2*D#Qf>gAfLBRWWY~WO6@=3kwq^;O; zNKhUTpd(~e8GVHYB0)gk^p5y7A|G8&flq#U<3>8rH~;hHPQUV+Ni$z$Epj{6bv1lI zbM%+iENR!5Ufj+N?(J918lOSqxqQ_V*^JjeLusAIN4}4pbr896D1FhGQ17o@j8MWQ za^o)7F57Enl`8VqD{c`RvG$Q?wP(3GGoJSHdgs2emGL3v4yvo;!5;1nuok&g4)0^Sxu#85&23r1Le(?y0dtym}Y#vvpW&@h8k zg^01ecQ}&R=$j2!^4aX>T;D zuZ)QB3%Vj@7AnNtLJ1aS4hj=c2*M1<%kzeu3wH6&!_!%zpq!J>0Qiespw>io1}(BI z=@mw-FF}4TCzuy8(}%w7iw3I5izbv+t?M2AWSFvO$D1Yw!2Wm<`t9R~(<(Hok5!sh zL`ocQAkPRbadb;6S(1wR%7Xr0$y6&&ja}9t`qn6MSl@5A+%J8h=xo!YsqBrnkaye& z=~wIMDD4}fta+b)upuP$rRVy1ZhgA5X6&vvcGrsSkIbnI^M0v^uWrviMc1Fd*Y|&~ zCj@d2ay~vjHf&UR>3_LuI^{+Xbfd=xpZtcOk-I!PJ%Ej6gCOUvV(VBL}t7F%W1KzlD)APCA+>=VY8v z@u6Nx_~OlGe-!h-N#PWL#Tl!D;f6pn!XM+DJOnVk7FQ+90-zJfut@SCf%9e(qne@y zKkYT%T?eNjQSp+9sI>_LaHq9usK_(1CBtMOHVI0%zmLd7$J)eJ&gz{^ zDgGy9R-te?&x@RA&G*B9w+|d=>N;&~`z>@yh-H!_!?ofR$@%OqA%fJI@`D~Xy|CT* zC$7$>cc@>>%~jt6%u;UZ{f_6u5asfl$DJi>bH7Df#odL0?h?1=mS8J=qv0RM-D76F zUPq4dwDTHWi?U6xmiFW?qqHyaVPJ@-c{rcv$1F3|9&C%~OMJwv_#^{hmou+!=ZW7> zGl)UC;@J&D2Pt0%LCh9qJ=j1+LbF!&J?Y$@v@F>n&jfS!reQ36W2C|5goNSUk-C;` zJYNCE3)wmh1tIV0rP*{7O2Uz~W8>K}Fe4AGVz1Q=wCB8`0l2LW+1!%E&snT7w>>nE zJw`&aN$MCfGZO}K<(8e8CB`?f;(uc_rnnA}UlUnj>|BwCmE?~TU3i<_2%enjd@6|7 z1txsmZ5|k^9-*-$dj6YtEpP0}_1Y*-kjl_V#1W+~w48d@S^QxL1 z!-^1UVzz3YYe-pj2t^ByW=pEE!A@WY?X#uzNr={lPyOJjZ{*;6_o~C%dH!Q=Bl<{f ztlu&X8eV#ZYNqs-M7rH~W6aQHla_l9Gv-hI4A6m?)q3bSgTPzS8JJsJE6%sZ$m8qy zIh4}qnje{;uGz$%Y361JUYOy3jtg_b|4mKyp3eRkx_ZSQ@Q$Y|nD?d?0{~Dt(6AlhCbuPM7lgF$qMX-6h5?0AyzT!aqS(y7nRk`bNMt3mi%*`tYBVn zmO0jrSoO=nV>ajV_Kve#xj)0{u5{Zs?NwENuT?@E&t0gv21k8u z5OkDE$jj=tCo60VscZ2?n|KFuNOmumz|AI{Lj}Bv`&mdJ#8jW9B^Sv30)MRgB0CJn z{#5paJG}~8{-N;h1#^YC4+hvP=2wW{>B*qG=L#$&9Cx*9<)$qR zgNlbhZ;SFhxs1c0sox63;&@ zzdVk=_h4Xmv~DqWegETmV1e%JyByqv=ggG|QvKJD*9ZX6oe};jD}QduI)@qpwy=Kj z^|!FN_j;skOgio>?z-}*akWk>COxfEHc1cXh0g}Q1CS6lG}$wQ`j)m@HNCA1*QJe= z>;ei=nITKj_UK#3L;28iy)<(8)WoCm!RDtQP+lF_#F?{t`({lgct6_6{}+CI*Hjp_#yE zzqm;$W{}FBmy@s8g4}AL4yVIv_|oH6mde}{u4EE|EB-sxRbpuS*KZ4A|72ox)&0I; z!KSGv|FJufzn3-oIP7V;RLq^`O+}zK6qZCx>ywmDK~iaf{PISR^}s8KX39>Q%WHoxMHYUJe6vAhID#;S(m!kq`}GUmOnlbcOnFq z^DN$r5d1{~x}@&n9k&i5@#7{IwMt3W)H*?^h?|WSR%ezzYoBU-JuK0GQSvS;M0*!F9l}V1F5!}pHh|H zcO{||jXDRh4?g5Nb(kS{&v%}&-b||g-D+-n?n#uk>fL=YTv4%@mDP;&GkqQZb6`!}O=tzq)$gM-*LvY3ZacPQ)8GClvdi_x$BFkEUbpx^{Z(@q}2>-)ob{F+J_~ z6|fc0DsB}a-fcT3*!C~Ml&>3O!Smk}z3zQ2m;QN-4!%#gDlhUmmAyGxn`A`s^MdB# z-|fy&1C#S;8x`gR{Q|96ttLn56$?1#dK^b3_ketX-Zu@6-CwS4?Jk?-0Ubkkw4E-9buNERN+{BDqCVAjv z(*jBF)1tlvR=)o4a`y+l0s)Yd$N~bAA|r@)-?#j@Vh#xCtWoaW zC>}_UT2H345q46US| z%d4MBf`hax7a?|+W~s4+u5S0|22x}`BNQ3+%)pZdJ6srKwKQW;>`8)|Xrsf$ z{4zspoeu+5K=Cpxrbs@0p50QBx~2eZ$+ggKdFT-F3Lu-IFRQ^+IY{qFVy|1@zUuao zDZ>`WP7b}rhLP#|rilQpA0@vRY!v`he0s1ZCkMd8}%_R8g9WZb>7%~XohN5JvGY=9~cAmRh=%yuna9GBSln{ES-X@u2+}f zfMtWVDecUX!U3fjVUd?b7XdA+#y=`(;u#X49M}``lvI;WFG{1O%?2>ijD;;_Nce$q+kwC-3vWl(}z z^%Ku*cJ2j*6-N>pqxX;3&y)HUA_RzyLBsF-w#J;Z>t+`wEU5Rz53pY?Ve08kS{Ljd zn`zn|mB@CS`Gt>Ni>`uLc~;nN+~T~wv)y)vKI=J#=7*8k?oL{7ShrOkeLd42r7!uS zGocrTe$%A8qkwsBwB+LkQu%Xumv}S2De>{Ih*eW6_oVz5Z^v^YNMtQMIP7`(t*xDh zgg9LQ?|>DKYHitqDH9wUWKtFkl^ATLgAh5n%mt>(?`PppcA1^Exshvh=Blt7jlSn8 z$=RhNRQXV#Z0ZDKdC@lNTX|v1i%+6CP^sMZyzrLJls&tu`Q3es&)1ZFUOo998n`irBab%1-<0ov7!~5wLK;-di|NnuUN^O{xa!r?ugpCRO_E=uf!5X zZnD|_r$=A5@jz0%kkO9~QJgI>taP6`@m6Vo{u70fxSLVSIW!$V=e4SK#1ppl#cUqlF3BDb{-WJpVkT0#QG0wxSrPGj64y1=;$_mE-58yj7zWKd-1U;ywbZ(m=X z#*5xvoz#sXA;~vtghyVm(~pHwn{Tp_nqN6ETMnM2A2(qNz96k`tfsIiV`|i06+?p! z5%iH4zOXZevV@PsVXkp$`s72;`xpjhF)f9X_iTUehM6WiXIt>mmH%p$NXw@$lF*}X z_kVs?+^9HiC-6nxVZ7*%UgXU7H?)`nv6RHF6qQ}`DXzE(#;VT`Z87{F z9g-a@tHYg!@7~3LGE$El?=F5~m>Y>n%ap~?c`OzCE_^_tfMMczGFv&qNIGp^I6#Lx z0_mcQ2$GZJ0T6`n&Dh8Tim^~H@I2Ra4w1B&OlqM!@rvno*T2PSf|?m{lO5WhOC30) zlFf7vHFJ;Vava41c+yO3Id2VJnHtz${e@j~XD~s5j-kH{L)O^PW@4~40N>l`cmnl^ zizl_uP0%m6KTz)78%4_HDzdzzw?p3Bsio`*7t2;iWsVqV69t;48;y)D{3hg$93q{y zMc=h_<7L1!u$#D2aBDchAu)T(MyuFM#4hZ%A^SmNIQ<{4hy(j|JW?1QD#?bLd0lhA1X3kOD8QJ84sja%x?|f{pzTWjYqA92-1J*bhA=I zjyQ_ZN}y7ivq_$5ShXMZS6oQqZ4u!RT9t8yR4w=_66GagDt()JY*RQczmHH_hXbJR2yLx35=ZYwoH-DrV9>TDlGzm;thy`h)X*|rJ zuj^t1LNKgPi*ct9RBHZR%g;Y4#r zOziVX-u0$kh1g}=0U=`gbi&V*hN-DOzF*N})BQWRw&+q^72CK63!P3Cmax6M&)G%X zHqHG~1)EwJT)$?Xw0>(1`0(dHvM*dcx^7ucaK7fY@XjOc*Y!-xl-JmAc;XZT;29;G z+k%HPw6cP0rd)Diksz$tK#~_203`k#ez?9XowE93Up9kn1#C_sX-R5|jmrzK!p0??dxNnl10f--2vVwZ5GOgNPZ3)US4#T+7n=Ev*wA~^Vxx@>PRba0nbYES_3|=rk~CR`RJ$G*L`0&NCnyVmuIp zGYUu)(+AL9uq=O$9je%cL2awEFpoVAo?;R#7R@_UKp=bR(dcDAe=d_(4tmd&ZF~nN zeg%K#^Jp5+phUdwm;3hXb&^0`7*)GL62HyIs==J)tw2VW0Nc{56jKedcB&!D)SRwK z+1=0lKW;QMF#i@161o0f*~-eQE00`0v)2&RY+LUd|31GyjkURdvGt~H!msnk`#*p8 zUrsOo$bIx;^H|S%-}YkOBPZE-6gb!eu{RJnzXIc5F%Ik@^=>pB<8>?{&xPC4oSiNa~z?X}hPKT-JQqz8D9?_^w_ z@YF+(GeGhGJ_YRTdEt@jBE_Y|M2)0rv5K{(t!3S(78rrUgZ1z@7}>Y{x&#W-ucJw6 zwzk0lawM~kE;EaDDHMPzpbsV;5rzoD@Xe55CHIwQqF}mvf$yw+<}i*DiSIZr-a6i9 zs0dt;F%0kq!vPn6BBW4z_AANx_jvIPw!UV@UM|_t`M`agZp&M_T-H6QYcML+y~iOUzev50&L&Zxi0HpL1fL<_+B|hPVj;P#0N={)Va4~qVc>s( z_MNXpdFUeqa<2OFd~LEz`zcMs2{wsNBTiJlmwfO3RD2B8nLKuIDcATDTeq3UNcGX- zy5`3ZoSP}X2W77_d;glphle*)?-rGB6U0>a;4zZ6=-M$lY}2EYbf}6flfJxyAoOAG z5VNv#$Tk}Z&U0#rJP$+-grb!MB|KqO&>;BOabX0Utct${jj7Q!VH-vFPb0Wjx|*a(O6kLzeqpn$O%VX2Ua84?)H3mE=}9VWv* zb2|;!w~g)bxg@=}$-dmF}MJ zKH1ltlbfCi6}_$Ft+Sq&fBhb(m;4?p9pPR+w*Z^)=n79HSX@=DwE|;`I(=Z<1SuDQ zl<|PWV0w7W3bnO5U{<`KpcHO|;sBE1V;Jd%P0qfN=ZZ4^lwn|LU zWn-se?CxR_{vR4y;Pt+vDDx65r?jB=!zzeP&zsBmKO^i~6ML__1xQ2x=C?T%q63-M; z{lW{1R7}!J`-~SS`wSt8&q2i737h+f1*+TpiI*=y-DsKxlV=)G$I;6a4w={xLQ{Vh zlr^AphshlG>J)LWEGDX=`v58aoHRfl<_yVqK z1IxtoHNwoMq6P;&x$v|}x7Th4{S(3`FaP{AG(I&+PFPH%rTaObV%eU%y>fbSohgcI zdpdwtZyhjc+G_4I^j_iMHF#A&t9jrMo%PSwpJY<)HdWp{6EwLR?|f9A`YsU{7C2F@2%k+aLc6psf<^&+G3sNoSKQX7~!-{vOz>dFq3*Vpl`}G zZAK*t9myP?MRQ#^y4_RF3#YV!DWZuX>&ZY1u_3}@mEYZ#>5Yfp39QMVgY)Lllrf=> zX1tqtXeP2m+uYCL^uu{%eQRMatXCm)yM7T_VWrPoxOJ+HL|BT1D08OCII=WpV>+1s ztD4ja_tTFob$+*{9@YBuBj)e@nQsE!THi!*gp2%~?jowpm5B#tKbdF@eYt{mx5rT2 zoBO}{v19B{HT)Ry`EspLrRl$GDFofNbJ@xpLM+UQYRadQ1EgZgORBfw{dsr<&#B4q zl|V^c@`l_i$!}qE`%Lg{Ff+Dq1{L*^QvfE8k_NzA$Lx7fP%)e-5m`l7E3yws{SCCSDUe!50mSNC3Gqvu=vF5}+jYnem)u$_^E6a9lL zpNFd-Kd!sB?q1D~;b*kTS`P*|pQjzZ-JuMOhCbswgbOCIWN{1sEMsSaKoHSP`7kLw zI=XUe`Z{?+>D0qkwxkggIL&293!rRTL0*;uX?#n~7(FwTXoWH*>XZ_SZFjE{28^4L z!U{~)g2TdQl-OlMU5)n~St3sv^#+~Bj;uJXcHtnxm3(}CP`^lwCrM43V)3|3l*8bL z&N}tScl}#SnNi65UiF({0n;yAnR)g#lngvpyi?t3G)RlfgZd`9Rl4ps@Pd*`6}B-E zJAd~JpN{#igo&B4_iD;t<&r8tmfzUjk1bdHH&sGXzqe_hVs&+P_wxSA`0?-kQ}(&z zv=R5go=wvRic$3=Jt@Uw7mp|ymd2^W#7SaK9T5QvLG!ZcrKx2C_XkwU^7dq)>XLbh zUxNUl^ayb^G?W1dLer~=APR?4sG8+zZpQ?p5n=S>r3E`Wj|3=4KWCB|OStf33H*)N zE5e2bL+c0^x1BkW(234o6f!TWjEM--)D|!?zz7hcmY4WRhLj;5)MdoY%Z0+FNxt%G zkcG&PmWk@gv0xW!C&}t(MeyPEYi2Oh1=xA!Vbirooat=Z_DM;Uv#l+~`h@Bnx3qgs z9nT~wYF6?>JO(-juw*9m``(9W|7u*&*C75kD4fULo?ECqHBP$#qgS`xRGg@M9AD!; zahEW;|ECFIih4NAypHc+%TE^g+>=uS^Skb!Vizz64jiGfhgJj~k$KVVz~+zu(UsEm2GqdCG9}*e%&=l6Jw>uJ_B=%_ zUs)-1)iV88Ca|YJvLVrFf`<@_F)g31NZEMcm>1dfOo(4rg(n6>le`hnBv-viIBFzZ zr9+buHlJ)4it77~^;!Recl{F0c7VR9ETlh?MJIh4krW+_8BE%@ z7Df~LJ-^9Mi>9ffWs>IJ#K9J|+j5HBF49=WLq@}Q?3oIX*VmTU`Cf-bDeq;k(u=x+ z&33QuT#KkKb&sz(+f*u&%bn}At+T&OH0(`UJ5~Fr-)8L@eQL|`IoLW8yEX3m`zTAj z$xbAu>iktdC&SFF0F5<1hO7o+NG7W(kIAVDn~=-o6VHKlv1dp(7Zp}LcG%58eI4VR!D}O`QK+ zQ~F&bIMj71Een?k!GIqS2pTlUfnjq#_d@|0;JEZ50635*i;fZ_8lZLzgRlUDYsq-Q z(Z^P}!M3lfLnEDRaK-mKgBNwC(okh3YvC4|vAvEkdn{uYJK{VX;`j6oMSa*a!=YSg z94!4cO!(uD)eU@XcH>k$-&pEcw1n9Ow(&R@gHylc7cw{aZY0hA{#fM7sI`_lpdZZs zE0V40p3$Qy8dsmO2~7r`E~!}B_Po_SenQ^!t&^D&5A2J-m&4{6QD)D$8;OTdyX>I8 zJ3+<5pXoEnjG^fhVf*B(2hEy|9+vc-+=qXnaQXap_}`$=?*ei1`PT#kS4t55S2<1A z#u)I_F8ikD;EB3%*V)qZ)II+6ym>r-`nlZh_td;-e}4L z#tJ3*qQ!ed-A%U3wgLT;XaGbli_!pB2!}YAnR4+3vQ3;x%8rFv5#=F0u1pNa7P5^t zO~JPbLF!lNWQeQw-%6Z+LxDoV7{r>Dy#iP;F{NEs%Ny8{JL2h$42pB+hk2uU7QZy# zM<(-?Zst~@@!RhWzq1&4)z@V(!zNCiDRSGYA(F^%qff1UfZtYC<_kX-i=*TGy%hI` z_@I!dQPrUSWp?RD>LW>$54XNIPxV1(P9;90xkn!C$NHQHEFa5)C8ffBtNJ|MY11`1tVSvFE8s)Zf2bQ{h+xXmX{V&ikylu;12+6M6pC zxw0*nC9O;i56F3r5=xJ2nx~S4Ea{>=d$|-F)fqSqY>buzq}{Qe4C(N+am{-07!)wX zn@2?ZiU)fSc>pg=Y)UQ=4ZddcNTzKzY}`$uKjKAa#NcH6@g9aZ&m#3M`Bm-tJU&m8W) zFg7NXruq}dz2x(tx7gwl`({LcdYjf*b(%Eg7P%}mwcG8cy^6-k{zXLF-gu{rjS=UUfnilQMuAY)0+oq z#xj(TKTHQn(XxWvOU5mrO<-Uw3R_%Uzui^@^Ae9BmUl($l~$K#noYcWBUXVyIYIHt z3Z!=%Rn6D0s+s7fILlaB|4T1}-beF&wN^CCpvzkQ*e=qzuY8_OuQxqM7`77qPOJGv z>XtZi8b>J#6}lS6vZZrn^~NoTL}Ws3clOg))YQ(_1A95SvC{o-jTarw%(stI0zY!I z9v`?!YPugx))X>fLg&jAqUlp&nedC+f1KwKWy(1Pj24H$p1skmI##{&&t^%`>HA2sbOd?!qmsEK};k1~7 z=mEtym(D4TCWT-wI3Ob1%L1RP_ve zGm21Sflr?@_$SY%T5JC%Vy9?FjuvS*WdFfo8Q^29p%|i7VA*m#%G7=(b5)AGEZNtj zoXQYzYH@DzXI&OBs}{KKyx!XD`0Up4*Z;%t%O&rt*PpaRe!2bmpZ5Lv^KdN*9~>p2 ze#S?*y}Q#TAdCo7$K(47z)YKJ3v7Zx0r3~&OtlGtkwc5=0ziY1KtQknO<0tm4TIwc zo5;9fb*nrKT1y0Wo)RIB??g)ccNRNla5Nph*Gg|a>%bFF2S?7AmJ>3s)LSb~57R|o z#3~|XE6WcaCwRs^DI@bXgv}AHs)&j{5l%BOxhElRnat%nEDj|77+lhjvClU`6;%EK zpUQ!#T9ilXTx}YavXS=j^Sr_d;tYG~i!5_mvB-;f`MOFgS`ngH?ZjhGt3)-j9@h-t z^!t`ic8zcD4isKwf3Li=Ccio4YT}Fe&@j$cVbBpvX1PZG;bOe~Z&URXA=&(H&+q!q z?eXq$^QpY`)#HCx21^zA^AGLxWSnMbW70h0g%M6dd~P7{i)=xne(5MG90p=AVG=lP z27-r2jdhe2Bca8K^5r!~v6NuR05|~{pgh|o0OFg@JPd3bj8Y8~)igVaMmA310}FxS zfv5qNp!2Gt`PyBSGrA%^G+EwOl}R32A8cbE-K`oj!6zjhKTq0;^A@IJmS=3`n!zsj zQIK_0e}(2mcam(^O}Fq0yIH1tj-oK_r_y-E+vU9s#zKbB^|h?f?*lJ4=v{>zCd>?e zm{Lc%2BzeEU)*5YNu?guzAW9$kWYvfc`w{{Typ9}zPP2cCG@rWN@sa&siTtW-tzJ9 z^3|ik{f1Vo@#jyn$PX!a^P90YqGw}@`@6xYks%xk_;66Piy#<=M-!$NzxPTu;dtEJ z1_M*qFoN73Lc$)Dg^s?+{}#>$Rz>ECN1F;)62}zsC^B@kzgoFq5YiN0}i0?9Vt4hv=D|`hyi04L$ z2Mogq-TjRjP19;Co>4Eguf8B@A`RPS7U8Q?VRzlpOw<`a0;3XECPdaRggj*bzQQCa zFY{CQd%8km{3)ea_WsD>p1rDK;`qz|_KeSO&&>a~XMALp`xkw9Q5PrrFZ!_m^!e~4 z3i2IwAu;QJe(5cKGOx_YKGU)hXB52*>j%KaS?}g<%1sK?gJ%fKvuZLUMq&=nfq)=X z{Jf$mFDM8L$QGbUXVW^_t5*L)!ZrOr-J$k1I5rm^LOPF)*P2DJ?;E@Gr8!z)2)`-} zBKR4~{RBfAVOoI96Wf!Ha)8BO&(ukf2Rbn;s*#N%9f>t%Y@GX~QbK}D%AHIHbgblx z?h+H(F5fuWFMW;~@_b<#@!`HKlUBp)qqj!Yk^L~v=plv3yHqDTUGgTvkGVRPc+SPH z8SzomY_~LOqWNQ(_c9`qRvD4+?C9TWB-@-A)x3x5Ihl5}T(&fvwG85hf!4 zXJMd+cGPPNu(2 zP+)pIH>9jpo<*A3pyGQjqJU?itHq*vxsfsY6Np%lq>uuC?tC2V` zi;7tf=CCTeXlkmY_{ckN5k1;4wvu@`x2H_UyPUnUxhk{yGG>rtVl`@N>q`aJ&sEJh zMX4t+rF0V6szt%%ns55$jc47~?awCm_d1VU%Wn)*_NvaFlrZ)7!{hLup2evEjE6AI zJXmNTN|kdX%3;EHk~xV3Y>Eud+pp4giDY2Vri1I#eFbAhkf-*-YUmo3IeAY3Y%Xcc zanZID=rE?aaz^Gc1WYxUdf*rxf;*DuY(gzgaSL?JV>jZJ^3t3mc2&eCy6Af9a7f)QtCI2T1KjLmTo^}dp{m#FiiX@*V1$a#6ze%D0qKfg~ zq_F-$&-&!xg!lKayWz;Z`W}EPCU_eCm>8GK#9Yc)*d~a&M{vemikWj}2Va3o8VD_I z-9{m5;XlLkkHV!83pgq!5SNt-!e}*YX-sMixC?_R1h0AnUvJwUvO zjHM`zm(kQ#l3la4hygDVNnErH1cc+srZ^c%MW{-BmyAFt9~am%eMb@(q+pG5tl0(f zX&&3wu$~2ezsSU{)6Y`W=kc(AzRnlf5$jqLmPdhS9tMjVVa|Pb;kr-RJZD+?6G+>nZ`@s%lUNG+8~BjmDGCxH*=q<*C*ip6tOtEnklAreZs2eDl*zEHzbX zsh$TZ5?=ZA)J7cK+h^@xLMfs>e(vaIYdO@j_gMnxVm(u(<8|IbnEtjHghi4k;E`UJy3K zO-@aVhnobh8z8gt8JFP{sNkg&SM!ALb*2q~B8Z6Sg-BHowCA&xW^z%3q=a@^9B^#3 z4L^U*bLsN8ZDfid^*NEc1QNDWOHB&jM_bJeGL^1qd9;@UM^Keh98 zW~VBNv}7tEMm`cJc2i-I%=YN(QmMnUX}((P90i?TCpoR4pQlRY&FhnjO^nfYWG75y zeWQvbGQRKj?U}|iyS`Jm>CHl4VU0q6m%yS~ zxj+G8f|?{e4I5&HfU?bTZ7iF9R4mT`2tmUV37dY*?8<|4#ov-eZYj&+d0ql%$73eO z7;?x#qbjI&qxk&A>|S0I7$uf z6vqmNmyYs}ZjhX?yiRF7qj1?i(J79XRfTI@irpoLhq`=tM5cXprBS53Tj|M<9EjSA*pN6?jY8%@~m9eKp_IyL?!h?^9Dmc{AZH<4X~Y!2*j8qA$ju{ z=k(+2qW_sBM;kf9dU`u0La#3=elNK<`poQ$OV$VZ!>?F(A$rtw_zgzg_K zjX>E=Be#N_>s`6_G;ytB#~+So#0oO!Oj5sPzI)#EiL%vgEXn+J#<6zna2ce_{vjyH zmzwLlk?!Egmrkq88-dDLyCgQ_mw&VCKGrHL-yEKv#Sm}bZ9IGPfLY6Lm_H1iIBirp zsvzJ)Sf*71)0gRva8B$vW*&iY7IiiOub(!SfM)OhNhFL$4hNgK5a!jt+%w8bz#Rid za!bFs#%?E!Zf8OUl@fmtMM|lQiI^!L-liCa&>< zl=8xqc8#1{s4c)Nax*bD&D)@Mr2+A=Af1@==6O{#_+yk%ygZ9NO~-ZA&NHQz1Zp9( zy@kihH6n?}@cI<$U}IJdN6(9zvCt-h$PC+#kWG8-BRxxYdUh8M_Of#botR7n9R(H% z4NN&HD(@WVH(kP-S+P2V`pl-eL<1R!$8*)A#9j=Rj=O;?g_5D>2twaPlM>(?K+3Fe zdAjr|@Xx6$he>1O_uZTw8C=+Pyf+BwS8~c8=y4vWV$*B$C-`-I+|n(J=d3RW>x+R7 zXv<)5L(_6*)ztMz+>#tDJtLv&W0sf}^EyfRy65AGoA$ci7k5hq#=E*zZ@;83gxurpi>aX98PW&3Wnc(0l&Pj7K6r_n*FVG{{#$Ho=siUP>S5d6A>P434za zJ~@74X7bPD-@}E)1&hTNu0Ww!M?yPkv>2aS0j&9oM3z<# zKb9myM6i=?n$8OC?f7aUzxzUP6GqHYSZt$e`eLX$Xe+Rg zco{pPD%#$%2EhBLU8yt&Kl1J74sKgcnGk)WN@WJO_Pg7@S_c(tk3 z$Q}n@ttj@@#pfZtsT953OFDiVMm`_@>X-~Pk22(acFi{-@XU4hfFStF{VWeM|Gg)8 zRd4-Q)*Ii{ZG9(Q=T(p76y>|`O+Pg_yFah5bn~@%x8E?F{RaxiB)?kh|I1zS!r{sL z-|;~$?3_+zq^RSDL`X~&LFE^4lHUzIeMkA6All0PwcVPGuTh~6A<;HhIlX3uKa9Ob!t zHMoo#DCR?2ez@9qS8@K;AAPJ5@}_X<%fH}9Rh|?mH<`;W#yLN+E9nl7Qr2X%<`7uVX8EPhtQHitV&H_J~Fuo#SM|`Ng*TfTN;e8YKlpJdb5ICd(K43G!x~RDwP_2^GyZBh3hv<^)jC1 zm5JL=3F>vQNPH;zrz}dYzh*&Ne)J@(44M3me1RDiB?J|DyFD^nF~eKnv6t$ywe*m3 zdjH|++u~xS50Yvm<^sN2mgv~ksBPvLwU-_Uoqt1NI^?*jxEW%Uxib};nnhW}I7Dl4 zk-$C=7Boot)7M`#@dix?}r3;ZpXYSo8qgHv7oFyUu#g1ZCb~f!ow)8Jj zjUe^4G>wUis+{#k_iN=hgS+Yu-t>jD`z}Ur);d3*+!3iZce}jU{nwQp_%4V~KjQhu z%Er6K%byQFo?#lPch@iIG(-0_<}J2Kc!2cuz)nWWxewEnLWW-_my<*-hcM}afKZ$W z#FlJmSmJ_$kUnZK25wnE69X;3o@7hyk#>fu0p?C>a}@0a+QXw3t?;7P=0? zc+<~P2Aovw_d6#gE0(f5f05bWfq!K+KtbfnMUXH5puWQ{IoZ!#iqGu%<-X(b@VggT zlEXi9%w#K$Aq^_`fx%~CWgbEbj3FgKKi3RiGm!<=t~P!$wQt94sROSV=$41A-7RQ$ z5Y&m<<{_27tHN26_-X;Fr_xW3i_}*uvNRV>_Y5sslKz*_ct!GC!)7)j|G!CLV&22h z{jqY21cs6v`Yp%-#DGHJs!3mwi1CK-FNfZJVIQgUhmHR>aUrkYhV=b1JIyto4b?|e z3DPJ{bqt|$h+I*}+|3j+$dkvx`hrLV&MMAjA!edf4lOt9N&G2Zx`n=0w6Ie4GBDZ$;%M0Hz zOpm|TiK~bbb^LCn^Dd9|#*eDf7rj#N)Ahu(Vlk^6vf}2N&1)g;oJ62F{|i4oCxK=( zUDoac_YIbr56+31#sK8Ys)eG+&V$L)ww#iwvn_E--cZe}5m{@p?A?MH)9UJ>+|@!lUS-eeSV`-oh<$20 z5rpE)oo1z+qF7&Fi`z3l@8Y~L|0|+8kv(DBXwVU?=la8}-!;jJ`z~HeNg{#I=g~k4 zA)|pg&pF4pi^}!3SoQ7g|nJPwYJq3IO zmP9Hg8$V|8OeOn1CgwwLQ}`P}NNYt|X;539VP7E*B>EGl+30A^pR7)xKwkR&D$(86 z(r($%89ys+-_kM&U-zD{kW;f>Qu4Pzuc@dpg#R&3K1btqaLd|t$Nq{-k#lzv#ouAC z+v>lo_wVjLI0Xm&hFOvhg5o9tN9eYGER_mmiie& z!(1}!sUMF?edE%xp5*&n2Mje45>)(y?we1x*T0}|W50s_n-nmu4=why|7n;0Bz5)w z7u%YbBStkHigne-0m8&7yj%|ozQ2Dco_qKx`P*va@;dt^X5aSkYpU@xef%JfD~VTHI+${4H5v8YqiH zj2F%XoT=6lODLJp4z~Q{E!)uS=(tf*1$|WkKQ^)PTZudcrentkV@_4DB#iso?B zADr{pzTIBG`*XYhKGS4_=2ghwvF_D(4Sbh{?Rpy}zR54Ym$QS2aoYqsw&y^I+@XXZ z1ge}|R9L6Y-9rezM1l`x!UfS>7&&N?|C4p^@U?d>Uqp*RAP{%k+_HFGZcM$J!yHr72B8(xQM>+X0~!fsPgqz-p~x003p# z;g3=X!y;g$B|}*3?oyDkTm*+kv_h+`%A?J%P<<9+L)*iic0evn$^$<)Vw2n+3N{T$ zwYE_Qu+d=e(SLspO~&SnoJ~(Fbl)O`cKe!3Ly9uJrnIC1GGaZ_s=>4 z%)0W>X4RpDXOd0{&F6qTSX3|1S94YC4Zr6-Zl^Q~h?(hLEdW#$zq z0XT#x->EGyttQ{&=*O~FpfFhw%e>&uBT)KwsU9v69LOfXC2ZhM-}dSr=Rs~?Sm9GU784(x z>pF~9^~22l%>CoL*$tg}>DxqS3rt4RZB(q6CDZEb1q(5Ink1zsQ)k*9`FB8A#R>`HQzNDX9fEl478un z3ri%W8BXAMwyyfroLnev&fc}i{KNva?AxSZ`RSupi{CzBwx&;Gl$+s2O9ccgTIN6f z@uREs%=HJIjZc{2{uWslwqhFJPnW+k35;q=4SDG)!b%bI5&*0>c@L0RU`W5>_n~KB z&m@P09}4=+#Q?y9G}&y*1$hH=gHx|^X+T?cXd>>-L5Dk!kS_%DTV39<(kCzu+Rg`cJfb-5)pXL zSJH|gQ0k5v&ohVe0}{3`o#!a?7T#iu3rhkvojM*f+r zwEa^D006y}3id_7TcvtLzMPuVxEfiE=7Z!<01*VtR8g9!*I|oW5^;+!gLBAGLXQT7 z+-pabJ;9*dAxX+T3~{3HBm(;FUnca4v)BEaRuygowwPhuQdCxrJ_OHdI;q{!r2nsM z!2E!ECj8{XR6dI$RlJ6Lv5TKSf9xp3ggooCHPoHwy)e;aq0uL|*UPV+J`ZUU#W=-j zE3y&s(N(&5fA+~CmR=O|x{J2j=X!W<|K8)R z4ZUxm37Gg~+n8G`9wlmZDxSixhew_|_&GnQin*X~_aE;XU}>ROr#4fA063-;^M^I} z%^6OPdj<(%`f9=0=i^l^aAj;!!;$Lf>Drn9|C(TuiJh@xbP6grvJf2Umd?kK$Ri{+75Q z@w*=PjufzQV@p8$K?@$!Lpz7q+l9$ZJloayw3)nW?|i>X>>3 zhkm=DjZAB~!i=tu<7V?x^LddZ3NJkD5JJ*Mf{I6v`aRt%YJn^Gs(5j3^{y6tBV6v? zx+B%>91CPa<&>b`-1a>I(%i$osTbvM>s6wRFJAVvv@AnNqI7N*y-Ux3Z=rS;>*W{6 z;~QQHMYD}yQFKlfc>&5=yr#kYi(%det{qu3|`MT3XyQFfsn8+97wH3b>^|_P1 zks8Cuc)L;~{q}9*qtHi;sew`31U!aOVH}PZ?C`LNCcPG0O=>C?f{CF>@xdlJqBIG6 zMq-V`M+=MSYJ076zi8{%GoINC@jK!QuQgEC-X2x~G-|nA&n2+?|6Lb~iOb2`*m12Q zeT$5>Za|B+@o#PHhUXiV8b)kI>-JkXv(Z6&*i4&;f3#~}2T&xr@CLD5xe4?}B{T&P zDW^#Jnn{%J%Go8v9egYlNfHN-=`iF~1=D;vg`~mw`Du6sdQbi|ysXxLlv<7U)Q<4Ehu-?LIQ6VXVxU z!q;!!w(;|0TuZe#O+YSfkwf6w4B3FAN1%zi%hS75<@Enf5B4cHoo>rm{5GDSk|jc& z4&6<(T2%i7g^1R}ueR=XeVB{gmSi)QB)J&H}kBSS8>a5@2*uNC%X zOz|tUk)PZm=QG2cliXEE-=`(@Rqqf)f`3N4RI44V1%O!b6yo*3|G~BOvdbejXGJrsKn|abqW^fug zywimTTnpkOxn?o?ZKlo=EZ_vL9L!HU^@6*n?jQkMG7J>4e4~w!CuEd4WR;GjK%3?( z_s1m7aK_AOO+1iOy%+HWDZv>BYbWd1P7C9}+fRRf(zWoDPo8o;=`?c48KZdqPMt>b zcItz5#QQHF6HZO*^^RJ%CC)w{+`4_}Zn|;*hN+-%;Bd-r6DCfVitAgT%R+EZ!!PN; zizNtWd0H%F!c$TTMDu9mTlV%h^2(+7t6m?NNI_yYkFtO_d6cPM6uw41)RD5IeoSd{ z(%bQ*O2f++5{rLyDS3HE1zMkk5pYC6I~d7gX~_He>NcNpl;XV57x68uAqrbG%x2?! z*#v$f#Ynu$O;G@+y7g2weadJW!ox39M`L9L_>^m@ZMd*?&tD^?!kAW4mfiU?RYo`X zQ~91wfMHhPM#k5P!-Qgu+Gwpj;haj{ zB4J*W2td50(Xkp=Gmj)h#<(d?h-&nrI3V}y(}Tldb#rE!YMDB*PS(GQVK1yuILZ1wr28`X$cQj@;ltuz4G_Ef?Q?Z z!iFPM);_=am2g)zTYJhTc<8eF>s|$5QT0NbR`lXIfFXuaVraxMRa($ab%8>c(=x0O z33VrYN!~n2kfC5PR)+1{Ut(MbU#3j>L8ou025h9_kFjz5ni0zw2Ujumo{X@DP}TIS zi0JRt$_ZFKeP@t?zE+ASO1gResDgIV?6QdYwIY;c z2d#-oQ=nVOQsT8bUD89;;$Z5b#wAjgHh=m$Nv_3lrt$BdZ0imiz`1N+rL-Ei7!cT+ zI+CMHbeKt_bvu~rg{xSPqLwHfPyfa#QPi7n{jhl2Xg&DWANSpG=W>29u8_&z{pZn= zB{DBn_r(CwKI4r~_teW~KZqD#=uNsx?3f@!DPT2BMh`-o^Q7<@T!cN67Aq7Q8s@3S zwW>pwu0ez~TXwcs$EJOvzXCDy{41u$8L*}Y-bO%&&M|K~5fhLz)* zIEnR@ZP&DN@|t?H%~N@yeQtIQZB&`VpXM)Ls4&RBf3`TWmm66tv9qzKfm0LsokOL} zF|7#f&44Wv8--A_NgQb{ymdmWCMAw~7SAlO>$f+vlrl9CBi1g-PZ6IS@3Jr2V)(O- zQI&|(mk)uc2f7iT!oA|f?($yaxewAU2{uc69l?zT7Dt>yLNY7{A2ivGn$vxb4VRTT z-veG5SxSSH=wg_W0Al^4BCCZhvpV&2bn5Q|};`pvtXB&9Q+?e*k>~bJ ztBnR6tM)Mt3p?#9)(ge%!i~WWG(WeYw<|t}#l$=oCc`nsfp-sY?%CEL8+5q@(=@3t z=}pq7O#JX)VWj|Fr}R*0oy-A~yAe$oFb{TGU+W<8RN=MVWYMF$Az~dWTNNOoSfqk5 zHh*~oLn|c(@MW}_6T74`1WoufHnqg1!Pb$Gck#;$Mi%gDH!m8OTMV}!x~s!i&&x{| zOq$;JnV>|Y!@Ceu2u*sxi9KORGd#`P+Nd@-{lq79vwjVYCz~XsOmLXXk2PCz)x4-J zEE?uHYDK_UxqwID3^1MBR&jK*dm}YZOx_8SqbyEW@oq$LR!_cu@=T2)`BQOe{VNr7 zX|=lL^$qd$*^Zxcd^R)3eZO5UzTKPMV`QDzeUtCvNCeXlRxQOwU%~?9?b&geLlLV( z6ev;M^C-(mK>+ks>VR`zYFS_CQfW$U8C}eC`eN@{3Lu!2egV7rq-}sE`gI0C7jjV? z3&SmWam?p0g;>7}jc1^Y zlO=<8F_g~DJTuBmjS-{gaVjK*(lBLLM>FRgbYb$GwH1&Hi!`)A#5p&|ojF%qc%%)`B zpE#Q*Q#9WKE+X{S!O>*vey+Z}Z*_vxC9BrPCRcMF)w;}Rd*g%;@5)G`15Vl|A{eu< zD(*_MLR!YwrY3kDJUht8*FQ2viW900zFJ2sz7OQPoBv#yv=(eDaF9ez)R6tmxT-l^oWK^2}25z!F;IC zO@~Wz*iIYn1v?w`G88l#bzYb5vU01QDSjY(8Otw zW77{Q;0DDHQuDNtj9U&3QhPI7g%6I%I`l7^%V4l0Hgn!B4_?DHj3hT8g9wnu_SBx_ z+ZEZA;sq0Sek(cE6Y@+wiwuMDNZ^J>eqKp>`YlRzQtP@e(0CClJRXcTdSKdXeB_W! z|NMQIwsS+#M|1aKG|)k>_l-8vQfi+?XjW+ItuW{M8llf^@a>zkChy9pWM>}NE;&uQ zQw%=--8uJvG1TRm^l8E5@PuUJ+K=uM!Xp8si)?fXHa#s!3n4-gi-c=|WSOIN8vv2z z-|eu&<;qTIXbKWDxx;g-%S&+kZDp4S9wID6KdbDluzO;2HCe)Cyg>DpT287UAm~w) zY^W?DsCyJ_xTjnaN^a&19gG4HZ_Mrhq`S1UuWF(JBa(G|LI08LVMLPxS;pmC3q5z)VDSdjl&16 zd}t^pY4fFZE(spuE-in}A*DM|1O%+z+ z%I<5isPlj^lFbBoKsA@8JPCTm2}=;b{vIo}0!1Mb|8_GhySb)v0!Ha+!(-3a%x$aL z#=&dDEf3?Ai{RVEQ40smAVXzP@;6!{j1y#GPmSOip`*$>&GF6u?2?^>cy^!U@a;ZE zXZKQsFmQa&S6OFcjQ;+aP{d}D{drls&XmI!pZht_onW1Rdq?PcNIguxshaa z^Qp_C`+dNV2U?9c*Udkk--Kj&&ly>L@VQ(yZTa@_aMpK3ORZ9D=z%l|diEe&LLJ(b z=%714H&`maMMlneK9NM0$9)@4LrIniN(3ap-q&)f|8;k!Jb+S_*9~FGu|cSnIjjBg zS2^imfDVEZPNv8gsrBtqS~7caNh;*IU`1*&897{cw7$hvtqcJkdsL?__NP+Eqtf9? zVLKk&a0vY{5FekptRX6(;)-Bq*$5wJH#At9W~zdj44B)hU8z#lll$IEieRwy6Fu~O z<;8Bzq~Slx@94tZFZL+|Zf<|0A7}eNN}gNu z|2~xy5bfu&t8H^}n&kfNQre?vwfpr$r`?xJjpg!jNxgETjjAX2QG&BfdxCFMMGGTL zg+XRu&E(XE!H8*7`Wi|rOJpq!N*86z_wz8GpcMk!vAom= zNLtIOwu8bFz@g#e1gRsID>kpFC&T!M*G&~*2pnD{dO{(+geY=AnK3oDZsa>QD9v%P zEzg)BwMdS%(s^(>K=&)I_PA@8>vyJ1GjopCK~YB*AL);zvbb(dInc_a=N*b@x&|iA$&oJ)bVt1hW<$?moUo{daELS ze}&)8x>y7mkKMiw8l(5G|BUeiKKy-ix`8xT*^A1~5IF*Sz?W>@bhNH5J zWwOWHQKYHP8FnfRFFJR3c`tdu#F6PT@_M<9NmE6Lk8&n*5qT6vDp@;W)4e+$G=XzA zJhDtxd5hT%%n7J(Irw)v);H{eW`658HPO!SsyA(gOWz!x`wMrp4jbCs|C39-_b~g^ zo%*p-|7?Kd?=E%1>g!}xl&#ppD~#fQH{j&ZNz#IN#`u3d^q5KEtIdC{51v2K7*H@Y zfBZZ{>Obc+0Ha;Pm?Q(gbOo7>9c_FQIFl+6)8)j$RZhi@f95MKIiF%I+A!wIA_|^a z7#1Al8CJwH%1cy*3oEnAz+i~nmjYG*PfL0H&C(%LJWxa8I1GKl$=rI!B%TpYLr&>k z@`Bl(pq)4tww%mQAuOX+g;GvtQ+i$!kCVdJS_WjV`PK%#wjO0Ib#LSN>eL~-4e;$G&FfJ3*v3{uDfz3>m@&|#ejoq<9-`f9l}H@3)z zT`PWPU!HgLWA_;jTqR$Jo1PKpiyZ?--qeqiHWUrMoGy+h!)hwX=l8ILy%iK{+K(;z}Uq?HT^y` zWo%cRLJ1r#Hf?5*XH^*0(3;^?RF`ny*tqeh(2$PFcZtF&QkzoK;PseZH`U@T7^L&x(`XvqG25-{vg_w;x>i ze)zX-Q1)&FJ*@ZInMhp+S-inS3p|{?2{G8cmb{^0trSdXm<2@e-=tvo2yp_Y2?Zfh zYUIvvv8%y}VOjVlE0PrcNvyvFVRNM1i%P$xK34=Q>Cp3BlyXAY(S}S$q{AN&098_e z605r61>1>C9C^0j2(<+>J2PrC(-jL~4ya@)(R~?8r>wmrsyTe@R3#$@MoZ^#aYw=! zM&Fa9_p^hwQkwW7CTti;t{rdU#&e3aXd{rGg#*cclRTgE|Pod>Oi3Hnr3Fhu|z!o?~tn;Ja*dHn}$2rvE5R(G~v&u)|j%X>Mb ztSK|p2lakg2>N8utzwKRd|?-s;_-PieQUsXH~HVBfDtqv+Nek5V`K`hPMbbZ zjCLtQ0^^(>8fmG0#c$|csE%!jm_ME0L9A>GUImj+VlKTQoMF@;kctj`^3O=Cyo)ZortMbne1p;`9 zt`NA`qY>e#M_g8FR&@5dNg#oQ*G>A|mQvp%YYUd!&^66B*`Zf6{C8z*@GCApu%|++LCOVM%VE1W8 z{d@18DhsEz!oqk3d!{^7G-FBTx8gbai_-jhWv={g|7WvJre}UXCwq^dpRd=MNRI9W zZHP1vJv{&QcjJNoA799K{*8x=q2doN#l|-#?_RE{>wif2;_y&0tSd+tK9ui3smj`w zg0&@|;R2CiSs()sZNfBBe3beZJE~Fnt-cLFxDX&BRl?3P7LVGonNu@#GiBrvl1Q$hjHALrJ%8JNwSAc3csfA^}(W>J2Pf>r0WxIC1U_Ae-ow7@Ca_HSn-YBtE zBb~oe?cJ3}y0N)8MN`ni`TYmkrIPpATp4n1*x6W#@hbMOoB4IjrHP8;(=Vex?%ULk zk}oeVi+hiQhIs)b3$XuQmK)A`E;1-#Y9VryV3b z5aP1$X9pMovSgrOdLn6Uvt#%6aa=~FXde0Fs%rVF^z_irkG!dg7KWuc4h=oJd7S)M zOyl`B2l$ZAcw4c4&YCphfh#8Ecvgd zj(&A^n<_Q@iXc06deOQ^#g-JXCH&%1gh`*<3U8s?dy{{6!?TAZv?)&!FGDWsg7>GP zV5(<^42wi36r~(DM}h;IE+T;bLaQT(ZJInJJBXepvCc-;D>_kuhzJ`>$QoMyC_<&7 zF|o$eayJW@mD=m*Eeo@UIT4V0V3!g$@rb|bM-gdLQVt`4yE{6}3VM}z_@TlmUrOB) zDp6z`7ZyF+{fMfTa-?<+J!cr;BrXod;5MM$9*7n#mf!qN()RoANfhTk?sr!Tj#zBq zrdd}1-eVxpRy-L*+a_M3G4ovKSNL8@>IV+SUsRK%!`*x?ctJvXk_ms!Uf1O$y$j3Z zVw5aY{orWa8I`Z?ue>iXUKTxC(k`AYzZe8Su}ztoQy_H5cF<DV8DHR_lfV2$RC-oK;vOUK*e7p}uVk*=+)V5)PY~aTl9KcnaNH1B5(}+x-^&_f;ITN$t%f1vgyvr z^nv}YiNp4@yO;k0LcSu3WD^`0m0&q5W#8tl5||?KaPtzLjTK&$ z3!ACBQYBc%e4kd7$<(E*ed{y7V}FUzu(~ffbB{zmkLq*Ij?q>A=m%4sky&$yH8a;tEkS1XVEwtYBsjd~YhD0aN;e;lup# z$$qw}IGM?Q6*bQR9<70)9uGa<`Cp^ZbY=y?D5(T zIoX^Ok4a-*ETajO(;PqQbjDe3(Tmw4GOdvp=AWLdx0QsFEHw#)Ed;$dZ6PU3KO^?K za6JEP(YXd8Frl_(( z2C!LQzD!fe<@@%UlUGta?@Zn3OB$OH#0g@fY8wcV^$j^H-zH zwrMk7%nBdZ**u2+`Ll6c`0}zG6SOt*}?!z`B9EQOZh6He9}dm@6ooj1M?s&31SE-C=kjRL*Kjy zC^Lj)Co3F{F~Q`lnWxw=!K?(#%nULL!kMu7@YqDy?@20sWBfb%ror7%FN3D)O^x^mE!muJjqrK?aqej&(+BSfZ|9^ z9aQ1(ID}`9JefNGKEw$UvSS=?Z%P_bG0)eST|kU%qmoCjC7>hTz@oexA!H`4$zk^iHZ__QK_u@KETrzgXAGwCUJ zv2k5qIehZ6yW)2isUdXoFG|QK^iaOj*5+ZEgW`3;pQQoFdc8S5OhVL^3!Xpx%?+l>AP_r}Q|0ed6X) zRusngYCkjgW=-vJI9h8F%n7UVEsvgDQ*HR2hB~X$Zx32Ej#ZJAG&}!E*H;`>nSxN+)1$m=dfP5NQIy_;>sz4`EWGHL+xNehT z%U+OViE_)*)skIdhap$V#=EQ3FuL5d>9tA|bx~hM#vHArN|upJH!7)d_lzG`ednG? z_^?xpKku&GMJPie%Jikf^8)Bsi`>ksSp-I#8Wr)u=u5D|Ol1K8WcjHdA>?ol!-iU+ z5D{ogYuTKE;S!J)8XXOq7UE~bBQ6!Ag%9CbjyiRoX95Tb;Esb)vJv6Us`K!{2FxD^ zL=US&=VEB}qsB>D66K^=84eQuc%F<^eaGli^8g5Y9O{RGN(9CwVOe+Pt5{`5I z7q#FZf~X8{nwx4o(o%UPb?2<8%-5p5e3y5E>5$w0dYP_2=VN3SGu7zB;P5c%7V^FR z*5>b>`Hx>j?mmw(tAvMd+cpT6yT@`PR2a6LDcjX#AUY`;#gxk=V7twf60^q)pc#(0 zwvIQ8A?*izXZxb0=aq^qo7cjZ^<|kNW2Hp(+4mrlX(_`83CFY9(ioYUMa*TqD0|_h zdT-SRarx$bq5v4Li&84Q+Ki4m+?{p4`D10CDvK?B_0%7W6$$;7&Bo(WY+k$yMTI65 zWwLzTLTosiamt$-yJmn5ki=rj)Q7+;InjJ7E;O2>%re(;tv1q%IkY7dA2?i3u1JL~ zEsqY%gwps8J0|8U^$%FiA_3IAwmA@pY^)&@`E6Ba2{Y5E3IeEn>4wMfPZ{~ZLJ@C* ziyojw4>L0jTXU7Qg7uxYzMrhnp zpT|>x?HJ5!PXN9$kvW_uP)bN7IgOiTPDK%Dy zs8|U9^W)8Lp20r7F8v!{_BNO;KF#UJd9nM{M~MBi>!sNAok7P>0#ybx zKQIPLuedZ1lWxAVdt!2SVoet>$H#-+pyTDVFJk)VZPm?{*aKP;4`m~0IJHe1!)bqD z_tW5YzQUn`t)5-mFD@sm0`m7x&%4~#jEm?%nZJd4qeDMSB=P# zE=GKvBH|Y@T;%8G(i_U4A&nybi4g6z-wGR(4k?i`sK)q)Im~!mD47wB52NSeXu7hd zL6B0ZlIyU&$1Z97lrj|16&a4iqvL71?9f#=k1S9ELt%Y_=GznhOH<-qMo_fbW5ZIB z`W2wfe663h0AIanN_<||_G-h2GWX~kV5w`R1$0r{OO5svLGto)a;MWpsukS63n_hn z9W^$0@cV1m++Gdw{!+bmb8mZF`PWltk1V-WlM!Epo<1i)bwkDiw{lYAPH4bz zY%~}-4QmsGLNxhR9WfEt#}pAp&)4uL^X&r|j1p8+K(XD2TR``SYAIyji$DpJ6z@mi z%EwI00U$06qbu}pmav)vsF&5bYfDj87-+)wWEg&LXMHx+hTt;!0mM0?h!DSPQdp>B zFKnk`-%+szMyTWLSiGCy+Gm#cWqw1Sygh;wctt(!kHXbg;OO}#B6|NQmSx23Y` z6Hs z)dc7|cz#Cg6h;|0Es=-e7K)+i)}dPHshUTlC%EQ8sTK+bS5yguphT_q=T;tFYPqxV zVEd9?5pa5l74c9GW9Mp7F62cn@?r}C)(ALN>ELhgw*M~AN>S&n!c?RdhUhvS(4WM% z%+~e3b#wZW?>tHca}#=1@cxVWmrc_e3-CgKY%7z!u`&^Mt3op3#~6Zq?|)P?;NGT; zX@ax9NRNJTLm&|Z1v}FZBZD0`Ra!#)K|p}D(P0u5p(-6YnFAQ0!9&fdT}ekF*o~Nj zQ*^?BtLsu}DIbS2xytj`3e+8pD(*%aONEW>Sc-}0Klo;fIk- zunMu3W*T6NOwuD#h2B8wI5TPPfnW8oU{*A;s$fBlxVaJDQw8#D-6M~dB|&lPZ@9FA zG2m334pu7cpYQ!R>i?&Swy@twN>TL_Wie#^N`JRJ;!fD_r~YtVyv^C~Z)%gvi}G5; zrF2>ByFEd_ZR)L(P^jm+z1wx;y9|VXlsUJ(MUlhtlz1sOdAVT+AwWO^Ug{EM4YCMy zB&Mnsg=6WFLH&)m83W>Gg^ij3(}q7$5enyIQ$F+L6kK`B2n*5Pvzdahrb+cgsEQSr z{TY~CP^+M#7UBzcr(%^uVe8OjNCLC=&;+$}x+*@%k_tot5t)%KPa|cFE#YQy&HDbN ziCE3r7jFp?1aYR>k}gj*ZMm=$*_HkreC zX1PpPqzxY?sc$;e{rLBAme_i;$Se~j8Sl!62`4rm!Fa!^_&q1A`Y5O6DKT%yQ|>uJ zo{zgmLa|v(Yfr-tR~Shu2}U&a#0an5B00{Rn-iTUB4i+hm(rKiwW|pQnHE93U}h|M z1d*CLM8X;$1d5O-;0Kyf`v@F`%m9I8u57a!fFOd_+(^=JdIw5d)ongZV|)yNs(25z z`Rb0pETXl7D(iTexl;;td?A586nw1gIuCLCg)KV&VRiR6JAQB1X&=|p9-iv4VzCT} z+uoVj!Y4G{he=l5!=;U^%7X9DWgNF+l;(&I?aVHCuc&|jle8?0mNG}G%krU}sT8e~ z9;Flh7yXRSMD^L`*19ZhXv$jQ%w69P(|Gdh+A)>Y>T|6-2RvDzs}B$V7smFw$nYAm z@(P7NEGz%@8L8-BPYSPT3OC$keXo}fJ0?o;o`&}Plsj4-CC$xgsgGw5Rj8tIrrMq? zNt~v({d5{otoYx>LRx4`D8ZU&-&+{y&>%h27KyXDQbP#)rCbjibqQnKl7qlBTT=^N zWW8}D2K`P{Di*L=B)5mOh6W-tgT+t;5?Ww1m_zp#`2rCJ;T*++(lJRI&~Ofb(Vsk* zvZc*WdShJ>_w{A^9OB7bqc~B;4O0+13`Y?*y*P=Bh9y-9QbAlHE)=FCL?PWJY6qjg zeXc%87qg9)3LWd=*_hW%`Gw^~m9VGDX+3^f_4WGL>+tF3IP=s#Nltqm%?ac-(xNZa z&2W@vo8WMzyOstL(wg8+_y2cMDEX9luqBd~efI*{+UgE~3WYY>YMEVDpbvQol|ZNr zP3Po$h{7{DNdgO;sQ$pw-)eF}7-1F-zM-(xHb1u)skMfyq%+IEQU`l9t}H3-+W!`pf9W;D>hjFWR*C0f4I? z*Lv}wmUd2a@kBAR#+B3vSwe8e84V&vGIorrAu^gZB^d2h$IESw%()aqBU9Yzc1E=D z)#3mt8Xpe=AFOmIK!B84bF-ocr!%Do7I2vNgw5`}Ge6J5a8)(UAnY-w!%zFUVo(G( zHpVPeuSkfGrbFg(BpM=FKtlxjW};FJz70|HlutQ;iyxOM;kze9GeG_58sFkcS8yRb zo8a`0SVq_|lNZr08VgkcHB+E9te+Z)ip;pmFDZFO%UVQ*lbBQEwI?B1sru2s+AnEW zG0*&#U`zUP;kmN;URw0Osy}|d%D?Cj2o9$CI(y|A>ZsmoB8i<8E}`bQ7_l&ke>1i# z(&tt&fXLg|w=h(wEBzLN0!EY=0QMrG!V%ClQ$g>+diD`x8lVbOXkD@RdRyhEp5Dos zv{D*QYjUcYqS1~CPzzqMEJ`DVZ11-CshGpjcI`etMin`=j|ME0W zseBMW$%!k1LE`g_5>d)>>gvoH22;EOO5#cEdqA54{1Np&N9OPD&@svE1>~7S;kXJ8 zT>4!hV)Qrqot&c39MG)>`xbu{jhI@WYuNa_qSbg^#zxOX4)UGccZUB?3McXR|IDZU zgTix7W`nni6J>7o|4s_CTxET)Cxu|$#!p=Go(I7lt&yylKfG?f+-7L{uX-E4?5eBp|zwyN*s-Y1jO5%1sqv%v2M1J_8NN6{EX`r3qOev~zG|Cpb-Gt%U0?e3* z2vS-+Mp~5@>)ATkmQ47)5^q`tG?_9?#6ppgTC+zVJseV=0`9ElfdW|F#lWRteyftD z$xBmN(TzTzySf6{My~#y(Mb9m|HW1#^%lFktv{QeU;2jvUS7UkXMcZgJ1e`n1p^Kd z!mQth9}>-k5ipj4(5&f$P!izQM7YBop@$ggLrW4gA{nySL@m%@%cjD&k$44&4jHNs zj=ieubYLnBT#w$95I8WTjJ`&RzbgrC-5`a9btjISzVotNkWZ39J4WjXH>&D3R9^iC zDDrgy*403Zsc<~UO$4Arf}hccoTYKS$8g1>h-ziw+6=E76;I4B`*WP9Q}si!$<|Jw zL}|22_8p!4-}=qesS!+z6LGFe^fGdx)w#xZJpHkhzT1uRzO-|TRzbICy84mni-8|j z`OYb?=Tbgq{k&`b`;@LO`Z4zJOYPq2T`f9xHC&9C-QjM{-z5i1Bd2w^k5b_ijdw!@f= zoHw98ZR^rNTo51ux4)1oT;?|kxOGk`g&7XSby>hxIAWDWq@X8Fs^ssB&MT$=Y9`e$ z6_{ORE~7M6mUX{v0t(d3HE1_@k%*g|?>iMMG91zz zLo){nC*5x7gB;pBOriiJ2FKnWH)CL={Yof^xn-5l#|6;#h)rV^3gsN_0hw0m;Dl^Vevy@r3R; zn73Smg0tpU*iZP&;w~xR|#B*&3pd`g;!^spuG}O zm%l5J)h^-nq(E-=T0Xow<1AmxhgXrLLwMCc6D6;Js%$Ri? zri|6V_9X?S_;1hOZYD&HeXb@0r!d{-qC(*+=&_pNLb(uT9|zpVWRx&+ykr!RB?L2K zAW#xO6@pEksIm_IdNLgN8mES>#2ZbeUiL`Dt45b9E;$IoMkJq5poe0!E-jG!R)}=# zaZSLu>tw=@VlnnK+zj+NtiVM3teP>L=}_pGD&i6@;lz~$t*R$5bu5%#o)ysvYq;+! z$cfjFR2a<`Ayy0tLdLd{W?#*oxj8rsCuJT+7IrvlAo05GqRd{YTb~=h72Ctm^_>Lm zapiF6QA^l|9O$p{rKOghM*V%C?)6k=YV$PplcUX{{yP3D`~k0f{;5}A{n#Vsr)Ky) zXheKgF2>damD2`(2=Ktdqy%6F7Vu8?k#UdHsB=@r@{F1{kETt5MTH4|dXvqv)8Xb4 zE3~JgAlip0tV(!eW`Oa$l1t~!Ys2DbGA867{V1)Y7Jj7gCoo;6MMgc1*fFI}gJ{|W zVYJrhpF~DZ&>IfJ@~ExW^NN5WY*w8_A0XF-N{t%z>xK!}eMTNvTNK3fR!*6Lf?93F zSX{jy5r%Tl+H9;oR+<@SJx-tVIxMk$y1I?F@SXZrCu(N`(|I|6F8uN4?`sp)FXiLb z7eWvk2o)RF%o)cegAl1!sPHo+C?UbglrhdCV&9xA!nA@84ZE*^I?PN!%1zx`1dWMP z0vC@8a>=+LgpUPQz|$R#Fg7!l5(i?&G&Nm>>mqY-OGx(imE_$JBheB8?ZPUX@h}j; zXtcn*UiD#+IM|%1In3iHRhYhXnE)=>R%nw1(RA=#!4kkR8DUg>z=hEgKo2*dmL2~H zLRxis<{Udi7z`mSm#=CdWunJ8VhZyamPn1~{#07CM(y0}qn4uG;^b#QP;87@sjx+Ou(B?z=<+2yJ zRlyRH_L&uEU>Y5WT2&8u?3M8-{U@u!U>Jli9Nh*aLIyoN`TtC&@9 z!hg95O>@k|gd>f8w4MEmME^Bw;*{9Asx6)|gdL7nZW-|Xl;U)gT)^hSc zDByxJ;jfnuR7}adgzEqxUXyiDcLCu0lHft!pOvYNPwn9^&wpwi9&T*@7S$Vck06;2 zu-I7x5DpCh42dvnvmyooAaF!2l1dQXHydWE7e)(6fKsD}1Y2PAnNtBcQM^ObJcY0_ z^Qc)LxocfX5mu1r*Unk|h)%oCXXtEIa_iCAPBjS^N9 zP&A@~#3*Y4L^CwmQC!KR`V^>YD}oafw#iMu@n|!``xxZ?0K)58h`jfS_QVlA=OAxN zZD@=T{$XwyuD?f6xBg%hSu0HhRNrFZ@6>C8ohmGibXw1Rig$}b#M3@WgJeXYq+QJ3 zyzQ#igyo0(rcU{b@QSn8eKN@}kmvWU9UU>%alwE8p2=Re#2gGN+uFL>W6Xj1k1KzI z0rG*Nc8R!=AxD2Ak?g{TuHq~zH2FA3?KoLk)foW618^$wI~ru!z-B}M_-!&+)huG1 ze;R>WoOZPj4uA(%m;z`g5P_J8KnCkWI)o6?Js^>sG=SS3OhGS$K->VwbkUJPAjk#U zhSZGS-a|8Gp?x=5r@N+IknAjo&uvKe zTtUS7I=k$9+LQHHlYH(GVTc38=hO6tU!ODYJANDl*miEc{Ca+2`}fKDm){E!p(Fr- z@K0X?c0s2443%aK9jHct)D*rGh<@{7W{mQwkgFMv4qHFO(S5a9A2LUYpfgGdiK{M~ za*3P8#gd7rCGo7%6>)ow)uORb5=5*?w`! zE*-SG^gUkm2p+BgmzRzL_!8h+gpxCOL!G|@wYnxHk}U{PYVa4h!OqAKLs0CoDjIa~eA6pnOQLIhShhk&*(8+^|;ylmZ=qhnQP~ z#0=~IyWIKz&p$bE4>Y7-(;#S7gL0hanpnE;!7k9{>1SLJK(sm#Un zgPVTil4Jk`eJz~R*+_kqP?&gbHQCmJ<;F`=wh2k>~H`8fCV4bdeEDK>IE{Y zA(*f(PdGkGp9|H;aDOZ>6xR<$7^?)mv9m!Tl4?)ZE*o(!TuCD+TjdrMWGYQlVmBRJ zPhbtV*Ot9y!3_NY!|+ZCkJqk9+-{+805LN#J9lgH)DthWHCTo%dRZOKn(j1SCm$=e zJGp5?S2r8hFf}Sm!zNIOH}!~lU85=Knk15^zmC~%5eM@O-Dw;6oxW#trTMidoa8-~ z^h3!zkA27dZUOCs`U^gY;upzev(Ed!dl!yNp8eL6PNoN;sH8^uw+J=rrmwFB4B)1C zO`mWHUB!m6)z+o?HL7dt4;irXK^WK!X+VjE*Z@a|H*#GSq)Svpb(LIWf@Kw*KV=Uz z3K>4IGYP9!o)FuM5*sSjR0@vbt!1lM1O@pV|JBtV_~Mh+6}GEUS-hZhP<$L;b!v6| zJul>SL$DX9$#%`6vr(Ih)!V8SeX6-x&e`PXTGd(mY;=S^Dp!7{w9;He^lV? zTPYy2tGi(h7_`$JM8d7rXx=ya?94Lc$)QX9kHxgF&y3hVFP)?=?LgWxwuN$8|Mcw8 zNu=u|i1C>{VK~u5x$+cjz02Rw_+-xAJn8rnnbx<+!di&3(rSg{bQ9 zDqqs6Eo-8tbM=;l_29!uWv&%YgVyvG%=2!`sg8=BWt6qW)oQgq3?jNKW~UG^FFk{{ z&uP4M_2VS27nPk=Hg;H#SvV5YJ2;`{M2uck~@7A{-Z%q|Y-P6lIp zvRFH86GmU{5PIl4^c?s8o(!$hatt=m1!+IlWbUNV9baZCEIO$Te*=ur&B***uIb|W zOp0dTY7?iyoT%*XRhq1+3Vg#3w<}*9)B{HDjwd3;H)-ojmPRTVD+MbaGNi;szY*xd zpJGqq2E4jutkN+`mLquW8MLgm1Bq7KP$T`E^zgy7WkWO>=i_{7Ius$ZS^vg^>``k7(Q8B%EwQTD)NZ?Gj%^ zzSQz9DjBCxZU=Od#4^EaU&T`P$gz-nTKxw>MDvidxj+1o`bt~?g-hiql6&NFQ65B@&7*Hk+7Sue^E z2VDQjw|P$ycT}@x!BIu|;i;Jf2QM2^T3MZugilWrfrW_Hiww8C5qMp@U`pXmmD9Tx zvUPP;ryrpDsH+HzZb%gFob}|@iN+iFV1*MpJ{w_{z7zxNQ-e^|UPt3xh;4A{pfTsi9dllYgNgE5us+sHVj8@+g_g9ThxRw#gORp@G z#8zEKrmrm-vr3r1V;o!ByiJKLFT8*64ovT&T#Zh};f;Ei&75L54qQ%IvmCD!18KVV z2^^XP_joDHKDwQmw|-5kJ$)Q~6}Fvs>*ye;(QHvTqQ`}jh^m5J&C4I?%(}oRtf9}? zq;AJ~cJ6;m2-x;b=F(33wZ7mCw>{1AR$!$uN&d7;InzdVrCgFeZ#jw0qh$)-`*|^) zogCGmR;EW&_dxc-NcWk{WO!apl6<&3XGy* zV3J#H5$Eh~A%Kcmpmzi{5J>GZk&Y&Z@u3mAcX7hhDG8P_J@DRa2bMds-78nDb%Wkt zhL;XHYtu#)#=|0e^1Usb#GupDS==5q6(6kiA4m+N|_u5cY9_a8Q5sL%E$f>5Dt# zIFV~j!LWADC!%^P18YP(&rccbH?f!bMRa=;-<1J_$QKu;OPiK+n0QPh{N75(F{U zmtmlDXwkl0i+!0|2TSQgwRDP0l3qSO#62a}ZS$7g>Q7+h07MSi~XyW2++v1yH zP?8c!^fXj_pM(2EeXfo1=iF1h`X%og|Bp6LDz{S<7UzrHrtdEM zZ9plS87>2mNfFjUHV-8DytIJUkt!9gp|JtSN9tuyYIW?yrQ(hailD@nKY!nnd*_X_ z&dBnPX-oFjS%)nD2p03q;=aP#Zb@$w=gpVWpQ)<7G+`PKWfYw0%&=V-&`-Z%f;eeX}!oA0Q$A98)_=Ql>l zva%-=i*eIq10h~ws^K?&+_dW&nB<84-Vc6rgRkjJpEb`eZH35E!UmR((?Or>D4NcUj6>Loia#k?8ltNVW$ z<=5S>Ot<QGHry11^XcHvExSinA6b5342YXw0fCX`bZ39!19+nW zek7A;L9#G)*w2HaNPWrZsD^L3C_f)_I9P{C>v)uPbrAcF@T2X^ne||+ueyhDOO0qd z(q>qnB%Yf=&njKJ8i$)))mi`rOsozV|DrLt1-B2!b!?6{ukbjIvW!vmx|LCGzv zbheFVHagxE&5p~?ck6lC4ol_JSEB9)4y)aHirN9~-wD*KR;T0?d>n0N!@V4!@bE}= zeic}T8ECKTQpKM;p|@dH_aXHQ%23yAhX&3nqbi8VN-$#x zt`-am1V}*y>37)>H*^`Tu(TY@=`5B*Kta8+pFxvWsJN}K%d8MuvXMer#bH0_t>|vN zK~d}*NC<|wdyEE9We5&J!bUl59t7gG*a&`|4>ik-(IGJ51Bzwn=;YqA{YI3 z#!@T!ttf3oG<>i1hC`u+f&TxPOL;6NU^S zPds7qqpa`z@hI@@0-u02Gp9(Z)cpPCNi$lB898|aVRey|HtKVk)wObMW*;?lKKB^t zKc&t2{0R&&JF}tCzW~=b1W+0!6*J4fd=0ZF0MmMJ_<6ohqTVc9eJkjqp&_u#BLR5{W+J@u4*a9vB~kV{mh?*84qlC>crdvPc> zjf5FF;1ngzz`VqrRxUggyRAVC7b_Ym#QjXH5s0OdV|5};Z5*ngyjaO#Q%>Ta$5p0& ze#6_(%_5dO%?wk-tgavYxgSp`j_VzSN}ob26jz=2UH}@6QaX#bxjM{Rs`r?hkX_H`N9>D8O^F* z7a`Ov9UUX+j~Qa2Jrhv9_<>7iFYF*S+{Hw}=*QT?epGTTCLT0rc`0g+6I`x#U(SUB zW_ljm&@p}aZ~PN$#VxM>@Fl$i1oZfo|1h>R@UjI#kN%XyW-lx8-w}XAxR@i%y=o^&tF>Se~h|X4|oV# zT}o1%w)lFOoxbov%er%8>a=q%n!0mO9<1&KH`T2|Yp>r|<{I8x*WKUyPu|7}xKq04 zR!0-<2gY;gzE#6#z%vck%}mp`z(cW$FvA~C)}z*4Onn~9al=Irk-IGQ8L_olZHYJX!SP+_i0ZF{CKQWRjM>8fc604WL9eZnX z?jIjf6j*@*r~Q%0jQ~khmS|XbA#`W->+430T8FDjyQ?C})aTW}hIM%&`^9^IIWeue z6D30BH$Xzmze#t9!8>7tNld;G2EIUmK>X|y37fv3JVoYg1M`}Np-i^c)g!^WNVhb|x|@%x@0fDb zE@%#z0z{K*n{p=F=mNcjy#8ijIur$Tk-X*1EX$dgtSAxrCn&D~F(A!mQCCq+CH`oe zrx{Db{kABEhcv8C{sTWcd36G~sCz`a$J%LnFT+cRd6SoypH*o<6SA7Hni07*y$CFB z{aM+3WbbsdnBQ*Fy-@e>wb8zQ&$g%0Rlo7s^<3ZO&^bx~jz4V9Z8V;`!_+5_VAGXxcmGZCF#6X_y07EAmGg#(yuvFKCUv?hC2Gt%^~u=bxV7=`S=13;b1VR|+w)|j6opml#gTOf z9QscrF><$)Q`8J}Q8C_$#74vVR7%c#b z5vy563OBkF3q*j*e!fV~r52R##oA5p`Eg*h#y2k6bhgrd#rM$Tf%mMRXk$JpDq+j! zR;yS=Sgj{38axsgPPwgq)N?oh&5I}e{Y#8n)GXZ1vEir4`CP1B+xNYADioUUu$(?O zd)?ICdar?DpEDxt*Ujf{a(TOMTfLkYE~r?2lhS!EA^-f;q+4KT`ro<5gUz33 z!p`*17t+qw%ysE4ien#Eo`2os!n|P}aI0aEj~Az%dyF3Lq#eD$tFrVTzT4weEx%z^ zgPEfKWBI2=iJV&SdwZ7J$T*S+9&OcD0=e*~1Z;VrxG!?KMZ`&7LjX;}O%_;+*`q(_F@Q_(+ zH2Lya^bJ+|d}yaoo>sc5HSvM}{Ca0_MC%6*xBav(JR2?AJUUKMGX5@nQ(se)|DcbqMQ?2YvLVea2%z}|eg_;#vW-cq(QjEF zJmkVixv#Kho%y8W%UruME;dnn@wIerLid@pd&>E~dqwMEpqVa9&*I&jtq|6oWBMO} zGZ-l1yc)%g>iZc|=J|={eV@*DBPo2bo&4h9UVP$O(Rf?Pwa{$grClz@^tbv5eN!TX z=UO4%B)fIdl$Zx(meOuzYCE#sc^_bB&Dx|AdLi~-_(UdjP4&!UwGKK~J;ip-2_C0p zD{TUyieW#{EhN*(yJAUe+gcu@E>O!HGO}xL<3H-Wkbx&x7KASF^7w-ff~+WSmDkfc z1kM#cLuM|QRmJqa39_XF{|; zn=;D*thsI@k-7h>`RnWKTi^S1A=k1u73-L8MjYv)=cfv39j;8Uv$EV-F9zC%{r%Ey zZ%;vgh@Yr6AWpBDdH<7<3`@Hb_Sc&v7Ge&se=(&^LMcs;zQ{2j)>?JC$J5_DrkMD( zxxYy}Jn%^2N!D@Aok-#RmIk>f4Y+k^}5 zgo`ud5;hPiOXC9uv*^gcNKPtiQf6jBK_Zxy`uvE0opMISS488RZ0UXSMTu#)tl!9^kA5kR^jk02XZRTJCa9l zG0_}-1Jd?NHeO>cjueBO^Z{jhD2C@|Ff&xxJ7r$m9DhnPX}sh|wN|_w>y+WN5ngO- z1u=P9vC77Sp*FR-_xo5UC%0Q{H3jAQ1CB-ukZX6?Ue5UNn=t+H^Xlx%uruQk=2n-9 z|DbRj?!988{t5+`+uA6rS17!3ZB(dzU43}&viom#33H=U<=^ zH-rd{&!a;P*i-eajba3d!^=#}Oq?L;wfv(hG0y2?*(Z5~LMENjQrjCa18pd7$zmuZ z$1aQFOo%{oO~X^A+JhS+?12SrB_GS0@JTH^N|HzQ{zX`;E?dHq-eG@@^(}b{dTz?V z>(6oefJPK8&4xR9XjdX{n}Hax&1%C7WrZDEYEp~DM9l1fP7R6QCUYp)TL!r0>@U*N zA4E$z(=z2tBg06}U zT*|+FrBTG7w<1%qv?!V{iU&u5 zx{1!159X3RhLId^g0hf26vBq5$vb)RWC-n@_tvnxFf>OGR2|&htZ3A{1(Zgtk=%%@t*%-H~%s14N>ce*0#pXPE znNb*BnzKc>yT6V4^uxFqG41hNg`;VF{w1B9Og~#g64$7j^gPqrIY{+|(=b2e8FewV zT)!tC=Flc7v2tH(%-1%OxQ{o~Sv52!y8q&^l=g*-Xd$*{D#=l|AV#PjdeGDc@yI4% zVU9*Xn$59B8&gn*c=W+1u{^+x%nUHZB!$72zR~f8G6{J4vYg<@a0C8ce9ydwke~9N zhiJKCs@Q1}y&=JzxZtW<097*q?4~lEuUuwEzVf~g0b_G&l?*277X5z4A0x6|4utmPJiStCUrXDu z2bp$9=>9R3diaZYj&_QO9^s~Gp07O-HX0t)epPFE4_qSI3qGFj0sL# z*`C8D%z}`cVOHD(iD2q1`~~U@#nu%B4nYE#>fN8irlo9~jineS4QyjZqHiQ04#q}r zQ`MIpv#cg%0s->Jo5}?g_Sd3;TIAozC*H-uCh8S`R_laJ-*oT~hHUOt_f_4iHW^(j z>(65Fd7S?;VVJ***lx%0XyNZ^8qwh3u_hpg@o3!{Y_k`O#_OHx|Kd;WoNhb{IeG)G znf(t6r>OV8oYaC}MUntm7Uyf40;N*AbnVXhz(UjUe|Fh=-b82K4_jIb95RLB-v_G! zV17&-e2_Swf7b3v$#rWcYP?L%+-jt_8G?60n!Q8G*TW2ab5m<;p)W8PK$3s+y_t0x*NVn-umEx*#58K~tvD;1M*0NxB`@h}HJ~)Ej17 zQR5?6RQ4wItiHTOQ;Xi^O}CN$3BQDtM&W2o&b$kU zpBjlcMGtkU((h1r71!Vx^bdh0zp;E~NamlQBLj33uMDm>gGZfqi1~MZVgGx0( zXFrN~U5N!DjdVe?xJIw~KI;M0gh%A6B10EVO-Py)U!kO<;RR#dw<{7OwW0QNEwjoiDivSBIJVaCn4Bup?Ydg|S$m!e;Su@_-dh zy@@?%*FddlJyx4fE!PB_V6>**LT`9%3Cd|ax?B@Cp<>%)!dbW0y=0_gQ1+$O*>A4% zp{|kgp{#ZPg@3cYvhiPIfE<3rcOX0Rs_4~{;N>hH`(2#Bs`Oo*zoc5~zGL8FiLouo z5jL)A;Gv|rspJG7I!i|9&?GKe29<;>P%Atl0gE@KPi4-^kP6u=y_bq9O4>}4E(#wi z&mqX8Xlo5gpmTUpfM{73JG8|zmL%c>C;ex&(s{fF=XMUU(;~sWEQ+Q&i~1Q?ldF*o zQQ_f2_b)l~-^>%A=WFdcJ-qN}`FO;0^7MUUdt-WSk+y$`W+`*% zSM=l2lg`7R@=f={eWeyM;wTv;^XLZ&e5C5y`ohMKOovZoYMB{YSr!$G%Txh@x{NT( zG89I3GpYjWK7g(+XyA*iI;TX8yi{iDVS+E%8>}gawyl;xMO7iO6GIqRe}e}khvAjU z2Z_^V3U$is#1^xcJ`5BqHQ%i-l(u6AN{@aBODC~yXK9N3!;+3v?URYgzD7_c#rVRF z5_IMj)2m;IIuH$10blgHeqnC4k^;ppMtmx~SE`~pp3!ct(ly9?gL_tN=jyELjJc+9 zp)IRd2>oLeGiX!owXx)|`8LllKz8b&)Vs!Rg0SS_c_~?Y>9(dXjiEW_LA04W^b7|b z*!TNCC|t(h&pXTn`@QZ%IqCymmD5yw`C?cH=YzP7HvdJeC=>fBM2Y-1fec~NJnFLL zRz{b;Nm$>Uj;(9hNQgUw4M$8KGmcEgh(zF{#2}b?AZFSoYq9{Q)ac~uaR(jP$@@Yi zX@gUE)A@9GH1Wtol4u4yNq5ZQYHS&ep^^jwU|dLPC=r01F7=ge%fi)s-O;>INfIF?s-{kuf68 z-({**krW9~X)&r_R-i;s1B1d4kfByYZ0ap-p~)63q9n+{A7nbk%{(wY^lm@JMv|aw zyndCST2}d*cl@!`;;OlAA>_|*sCzYgxCR%sjrYiRKYdJ}Z#0({`TjmdekoKa5haCN zle@U6E@4SivKFM?@kZf(BnO3$dClOK*3k1NiaJn{<#cbNInwIGZ&0A6KwoGqHVs}nf2|8XBT)UE z&2rF=9!{1_#HnohK3?2Qjt92mtom+P5RGKmZ$l)9<48eJ-$U9;&{Bu@yDXP(mjOJWmZgU>p#IbyT!fD4o@%gy_a1BGOJ)KpbSIB2h(1bvMb0mvr?TBc@ z*_Qu*0q_b)3U&NG8|X-rdGK8(#S0 za$;Y(Y?tnXWzKOLu`jA3p;1H?^T|9!pXvK#=fq=fzJp^2^ zck&y&5aohIs?wkqhKfkqSaUTLOpbziS+hR>NhE2sQde~35UKNY1~>DnKZugAb7PwP%g^|b)gqaVj zo&jdgKI|-LcNbSmo{C3`@hFrP8RT`T#mes=tp!=rQIrE;rxL`&;FIhCguSGs0U0MA z8UTrIO&nkaiOjdaR8=k-^GG2BTI-%R-}?FQQ6A^PcEwy5O@C;?%WJ4YaVY9d&%KlFk%9aC?8<&|2el zwK}~tNY(VYa#SDd*~M&)Q>^i?o0W9&r>)ec(^vdGk!~ewCn?PDY*4y=>AUoK>+J_# zr5tzigM@#X>(L4?>KZvFGMlp<1g~$qx7_tEL_clokNQn)jOuxHJdO6=ZTFN_oL9MG z@hwgAR~6Srs&e`U92VwTUP(hbEV+T(rQC$3(8D*1R%jtW!nzsPD3Z+O+I}H1;DjxG zs8qu@peie`)E9eL+$Xw=ctinrm?5ATQ$&id2{*r;a`_l6>efIE1gJl6bt)eG#zYj4 zvojdw50w3@KXj--FUG(m=~@n~Ggub$Hi?;Er7IW+U|9ySl~uD!*v9AY50$8uMS7sy zGdWj@A+qaLk9aq*3Y2Zm@hZf+FW5esAuEz&UO%VSVlR8Q-QFmX@;gtkh3%Yww{OUC z_hpHXwwsohN>HmAC5PMx}K7#_hyWD{Fc2GG5XgZ3!=k`{&ynT0|Id8~&9#gLP*pemTzBx^8CTSD_E zU5Ipl8H60YM#dkSmNtviAI8FofS@tVuF7H~K{4T#J8cninB)v!ETXOG2oI+di8Pne zR~eXXt=JPkcGu!T!|jC0L_STGHKgFfm-GeMe9AliO4F_1bt;aoNdDdIu`rA^Ku16DLwn^R{I@dak%v+&3Gf%G|CE zQ^Nkkv|G|BLD12iZ>$_>g8NFyd4NT^^CMdkW9jkLPz^BFYJ?+;Wb@ltEO{c@Z>GpDV zPJYL3y&-*N?&@>yDWRzR;@=f^wL#4mmXd>Ju7ip6_ga^Z^Csi5)MS4qI604!oewnb zQiX5yw=Y)ytn9}=oj&zeb`ggedJpeEWBLiKKx#`Y!c56g9cnly1+1zHhOGrx#)92z zz|L^V0RwqHNC522*GT+|67CM{11-eEVQ8!8Wg;zo{h4iXE1RZJ);vC!J_^oOaS1IY z9K|e47uHBdhu`a3mG(<;pnq;+@4oL$fBr7|3%CfN}~jsgHhCrt&@eZF1TBse`d;w`!+hIhv=4fwm@@+DyD5zCR)5 zm@Cx%+6ox_@CPgyO>WyZnYCk!Zp&~wzwNmvE;U%#6VsNkHM*<2078_BD5MIFC&I&I zcgPy7TXEldY~&4yf^hNdu8#Z{Xha=J-f5|TI(*M|*^YO-UK%rqM)Q$P0nml(4+q-g z0H-8$Rx!uEBHs;z*|lD!l$q^!j-Y8O%KaaxvBDI6;PfjpJ;A8P<;-?c{g+P2r z0tm(C`lA$8{WXT9gX5^x5oOk-Z7%S{KC%&JJD)xolC-8EnOR7kznENDN)0`0a~D1U zD8a-A`qW}cBU{3PcJx)rucbRZ zt9wU78hckyMUl87~@L>k1=l`tnQ28z%E zbk!G_*#P#qW-&bMse)1j8b!Ympuh8q2yJuw;&bnmKN8JknXey?l!WBuHD$(yKntltulTM)O3uIe&)#kHYir8n9r_u_`n_wWEi0zy47~{ zCxGr&f4OE~-;1-xaP-uSe8k3MrTlet_sLY{`XHEN-#RgKDeBQpP|3Wy>fhGYvXI}0 znbFQI`M0=i1ZCpCBLt*jX&%FmAWSyJbZq`% z2th+2iTYry*i2$bRAxto&j*$dBjDv@cszaYxlyE>7crk5(Xwtgn$%JNEfcP>V z9%?JA0YSusDU$R?J4sa{-6f(ApAw1-h9nmaE_{RI(OX52gFTYzW7)BZ86ddi!C?yM zUF6={{3#GiYoR2ke3`u#qdQZ8oMzMNtCpG(OsR+H5>|*jroUVgvp+rGeSnww6De(! z1eZ1W0-;NHRD3PDoPnBFC2Wl5y&s3(#r0>=YS;XBqHtR9{4(c|P7F1V+iJvXp`R>o z5~@8bWgC7P{yhCK^K{+&;b7wDmAT4~XQb6#bsmLq6$rC!iCR`?7Il49{ zl&WK!dI%TPg@ClO5=rfH#=f{L>?Xc+dxs04AqKzsirv@S4V@W_s>K011jjrbRAg%bT~ zi4-_S1q9FpwG3FIPD^wDZ&3Jw#G{B(K^dn(Hm>1k)0O~3Emv9EE&wQq+YYN0i53-N z2070o3Vl_@rV7A;yJCmUkvd2N-oSa0R1L{YOCLMSFQNId$i?J? zYqnMgehOm(1qExod}XcrfY-D7s1w9WppD!x951}zS?SZ0_2UR?-S#4XXwCk-#*}?i z8o98rPyLxiQ`-ceH`H^vTKao;E0g+(&oh)b{r_K&0nBXGO2SF^TQp1L`h$2Lw?(6G z>pPw<>t-~Y5?}wb;WGF|J;<>vrNBLTwmMOcf1F2ZXqg`pqi=^wE15df;MlE?S970= z$XQ=z^EHJSD|3osuqU?FO37nZ4t(QhUd;I2Mrr4=3$qR4%3{x~R-tfbxQHD;F!{lb z?P;X*IXZ@;z97}7wzf#@v%X^VuznR4B=19ZN=UZ`zPhmUg-L<8RTJmGM?dKI!mk{k z?Xpu((AuNk5-9voSu8D1m9JDDFF%Gw4eD(+b4_cgf8gF~m2x<)(HJW8d?+rT$Zk~P z)p$aU{BA#g{Z6;a8vS7NeAglK7u`RtD&l9N2yr<+A(3<8=eA3Z_rGTW8EE-&Iy8S> zGm8jOzIw`9NC^2eOd?2w782K=0U5<|%H^=&VsIjat8G1PZE{$%Nu^a5&y!J@^#t9k z_WxSOc5HyBHR`L!D;r(9NVwk-i_V@i@%HnUeuOYh2*sjNn{L2yc|KA2ZG7aE>$z#n z#XrzEm6L5}MdKze+o;cD$cH5O&k;G|>|QBnH?HR~(+jin>IYey1t}SiZV?}= zo~oW^o>s3b?PXG?^F^OIBIZRa&0pgYmN8lFdx?z@<^DZvF z)MP0kdH$)4bSHsH>76;AueN|3DP{&t=+80`qMMH!qLcY8;#AWEopE6!Fy~e}jZ>|( z%z-sDMBI2WU$(Lo9r}&17(QtWxP2wZ2A{>15%UvaSo@P=xhKGwi2G-2HVvP+XhWaZ zQ6?(eb6X~`#BrZTpZAdDGUGY>70XLvCZV>_i0)wBj!!-pwYi-RE7UhVJs0Pv`U{>* zKid`13=g8zRS%v&=|_I{>(FZnAK?fIBxj*LsR!1<{pCZLiNP3gZKRm=Xb??Xq)S;S z^jMn6gJ}l6O4_BQoSYNaq&BEU!~93ss47u83GMsT`{t;Fw^oYx=$Ue2?8j!&IcOHl zH7coOT1G?cJ*)fd|1AnR&#o#AW&+bbxNIw;qz^Bhsp?%{p-eD?G2AcEP~0Ufb`R>j zD29Jb?D59c^qkYO?%r;R{XgGA$Z%lf%*np-afZ!~y)per!*U!Ap6e%qDRPwk$u5q|H|>#G)g zmbuPzWAEQE@Hz*Yj40=_@;ag>W-;mGl$a4O^iXqY1d<+!e2$G?RLMf{rcw@saF|od zU@%V`)uW2UK2YW(B*VhPEz-^xJGews{hrECbzr7i{#CjGpNJ|1Ad5Jp(LO@!t{%P? z*Lap#p7FMEj4yjt^Y_Nkb!@+q)M6`536G>R&JM88q*Apw#M(cDb;Qh>NrR0ar=iS^ z>#p?ocp|eBNRiZXW3+0;D*MQE;_@TKWP|g0y^NQ?yw<~x+G9~DZu|Dnh|?9y%d3^@ z)(V>yI=_48_SlhozpIA|fd|b~kA3}7{Gtlpv8dSr3#;Hsd0Loi(oh&oRiqzr)^F8ILL&kneVG_apB;0`Ss=7?M9{3`%ljAeD88EpIi=L=H@s><9O!3paArsf2s^j@}QUA{4KsjG)%3;6qJE4 z?7zLtFayWL4#hsPC0lTDw zo7MdI!mv#OKJrtuM_D8lzZ^mjNcFIN)Xs{sTW-D@is%7Eq^lGw*_|-APyO{`4Ca`2k#?z_-L_rS!7vF+o>lZ;xoK%9>E#!bR6TVN?gDJIomd6P>Z)tV zJ<|ecNIha<7n|BYKb*(2R5ZHx2`El-ORtwKGhj(c&{kh`e57 zcKAs)Dy}el#f8OCdY)d-!|Z7$N0G>9~8omh!Ob z&fLiu*cu~Z5xw}>Vcqd?7ByjBm#}esx!L}lXFQufJbm2lyuQW%?!4>H;Qn;4x3{v# z_vsOFFu6YmCg>p**qi-tQP_EQwQMjAYX9J}ju+nN_0pN)JQ?=iBLzJkYqTk|wqelV zm;R|TTfsKRVKIQ%4}=@6ET|2+rxq$**bf+-VrPvE0QY_o>-fH<4ZJ?rpWIO z`>Nh_jVH3mVYnpO^|I`SrbmAHN1oFjEm-JAjbjI1txoE(Y3sU12(f|c5FT;fxOGN? z4p>6XSu3M>i`y@0nNRa>@U=**1^9fFN}=ud+tD{GofB?ZZ____-acOM=gzd|raCPm z#0m$MgSOwCs~)@Y#$ZKhFALui?gTDaKaXOuTqY($LkSuYNAgf{5;woIp+pSH{lPIUVY0l$T-N^#i zJ1^H(VYkItA@b#eMIU)a{$s|uiRr)F<>#%&iycdM$#15*w`#YpQt#eZ8*9&axi>qT zU;Vp%c>4WkkT zf^(Z#63!+Up~=l>;Uk;t+_!Wq?90D2?w^kS8$CB5 zOgFkyc$$4AoMR+^r_a1c;Iku)n&V=GRpT%iJ?!HHT#*f~3v?LJ32C3~L#7TRXbBlAcrXC$tU^nBRbqWi>PwRCAH<8&r4jVXb{+*kJy}`SBJ5kO zJIOjRbzBdb)di|c5@r8LysOOTih7fT?*=JN8C1J@-^?s)pQ0d^BP7dKFi&HzU$|Z7 zUTM*rB2wAW)V-~{``@B)1i(r$pTh7003NE!^J=~UI5WfqD7TOp&Z9OU;XJhMUq_B! z;Kqq`zhBqxk6zEsLLbkHCr~#BMoAMqG<4h z7hCF}(a-nqoI{YNReA)1U*$1-8B_X+LeH0sRPMu!DsG6ydAP&MHJalXku#n9ZL<1X$N#NwqxSN;PD62~2#5x#| zV)Y>zn9(>w&)^Y;-zpjEZp8fSw``91j|Ph1@Gkq6XVEk?oK-Un2IS#e9xIk&^R77= zvtZvhzZ9$sbdLlTw-U87OFPE2%jlQWLVjDl7%6(E_4?oHes3i?yWx*Q7rYsE$u?%X z<1N`m{w|00(T?h;Cx?%58XH?V`y8de9|hYb08A2NZ$JMaF5mF6AME;FAnteZ|90=F zyZP@l_vvmB)%$zO{qNpBcF-MLesfMdiyl9(4-)pxdDlC=TfI>ZK--Zoq?+BJCemdV zdJjpj56}!jrqknR^$s!kBP7j%ZsXx`Osr}NA?W09KRg1k*Nwa$K!&RWjkF5}9&r8#;k>0)3;YIX?T7P7fxiSE(i#UD?W4*mm7B6mEwImWR7)5ciEfQ;Z`Gf z^JjdyxFx4#nM;l_`OEY0C^qZ!k;T-eg+;vy_Ib1QtmSgvL+WLk!=59-f4?s``91zu zeF!D^KH;TK;Q&Q@!F?kB6ZK5NDIb+`jvlOUxAU*+ZeumfTyau@z^BCiKmlMfM@wBA zAWLv~%10kO8Y9f)<2Y=jsTeOgwj>V*Ts#UVH2VhuCFR$%9*cZnjPnWig6^Ls8~Geq z?`BAlp*8W3dI)7WUs1NR!XqeAgjHGT#ax@H67zy9y|WRAWzz7$*@Z!Ly?}+)Q!nD~ zipr8}{NyQX+8&TzkRDJ@w^rex(Q@hftv;#wIMpa}0~K`0aQI6cZY1(Zq-VsrC`gjs z%bZrN?xxXB1YXb=dzpf`T4=9AhXp?p7fT%O(O)@6NZZN&AkKIn6h zBeb+EyfI<0veHb>?Cpi;@{5?AXx?~&&4=i-I?Ue7aZcmmew!>zXp}yK_ zXG8I%0qBcK*mO3rm{lM>8Dw8Vj#g9 zKBWY=?3Z9*EY_Yb*>rJ5cmW*aejq}@a{k6H`&CpAn_YV+Vam|h-mFsEdQEi8T=N=h z_}FP_jC$C`+y1f{kvXBaLJaU^PSnr7#&?NDb|}PBvfI+*b5B2U`#bxkG?xG|$9UlpJI6k`iY331_Y zG<^s&vi+tNZ+2vg7I#;+jw%!YN(yMGz_~VeT!|R{mPCiX-D3{2(kvUXJ7S&1F+i z@kah&b`vsXMwv7{)Dgd!o{A>E>n!TjAV@|^N8h8z+i=J@bk^do!&SF*RB^1}8#%M~ z>6+%|sIas0cj$^M?@X43R<^jSKo+~z#;a!HgK_#pofF#nqYd9>&pX7|m%cCJn=MSuZCgLn7ATh21pWz z-SSrdn-sjBU4=T$|A$!Fo$63^0HX+vjVQ#*&k4mQHnA#r8-|Kwah?ix-&k>^f0iJf zOsGChNzr?=rK_pEs2bV;ZmF+2#<-dJK6Y*+!gj@GG@&kuy=NG2@(CGld5PjPdy3k8 zn@e%E zM)ZhIY^@(H51!pFqI?dXa z$FzvY->0wn*w^Qs$xQU|KI*-U(0=#MSDTderRkCOv{$6XiksF9=cpGbz4(*|9goHN zBYN6V$$?zgXQDaYF#utRN*WHYq$%}W$HdpM(Y1ZM$QIJsV!LmeB*9$9?*?v=Mif4f z!W&@}ZW;DnsXr-FAb2&DUFPfeDZ7rvvx%+9rp2A3s50gp%`%nsX#@9C%c-IedIH2v4y;y_d8qKAJa8Delmv*YjESLr^r`P zl&JG)0C`6;zBNG%nY|=_I6Z}~Z4lYOzJX+`RPW!Cd0BErXwiMP{#v@OU2N3J6U$T} zI!5I}-k(+BED1Y6C}g3ug|2I4oLV85n>LfegOP?>+&0;#0wq;fMY*JIi+{u&7RKkn zUNd>a&XaOKYhQMo?*81hy4o4^mwQLm>`&0-Pg|?vvUBwOuE;=q+A~dSkwZK%;_jD( zc))iH+3th#Qbu*Hv_eeLSvXpftSusx7suC3mcCPkg_Qv}Hc!lD?(ZKjr91zzWLyV! zXxDOD+%RCKl81t_ri-j>H^f1SDvCHli@q>a-}h%&H3z5trn3FMW%G07_OW95WxFC` zp(?Rl1zi+dUyG*r-<$QMNc?0v4EYeHwln^;hh8E>vY6{KH>3Ngvx1S4^OCZgA_oh& z(VMAeEhSyL|KSumpIvQPsi6=nE~}ikFb5Q31uYqY3N#LS!&$|;y4xd5Gm~rT^Wnxz ziC|yl<&VPmqE&y40_xLD#dET!)JQ1(Y->MrMXYn`8K3G+abz3!z!`VxA()cPuJ4|z zJi3O+qlCQA-N6QFYqGdvQMyvBC}I`;rHVK`FAkwO@@$8T=Gji-7HquQr4**0<=d>^n!czI=c9MJ$SI zijyl$g0ck~A-)6+rYUDUU-OZtxA7%TG0Qf<(X6Lh)%Pwkh**v2l8udh!Nz6yi~9R4 zbJ!Ip<$`BHkc;pT+el&F*$ceH?mItI4}jE=b4ES}#@ z*EPngtqjILPv)JKa0WD(^aYsh%q4|v9}FAkGYlEv-wKz-w>)3LEMc%7kORM>>h9!%>LL%CDKzML(2h&ib;mSP}aoYw7~r z2q`DJ;P814wVwScBss)166h@r`fJ5o5E;}KV@rM{oVw`CQPB0)qLjW=MPf=z_M}S6 z-Ns5oW{CCgM97YoJ?fyjlPIZ{i-0))d`; zXhJe#dn~TS>1->j#ghOMea16uMMC7F(ZP*%zW&Xc{m{jFZYP)lu8Ct)d8o``le`vqDJ`lRc2%TO$D@EUc?)oX!F>O&KkOqb%J1#Z@Ve_5TJqW>nF`(GpmOjPzU z_M=~$&Zht0pbRRxJ=w9>>QD&htt}=_QQ?T$c!pephXqbhD4M^R=~$q&gG)aHa2puX zXFS|w0Om6w{vN)Vh93o;jf{#2S#U+50Hv%DbcSGB3z(u3>h!-boRCZ%9!dl>85!?o znCshtuDQ`_JfKAbgj(I;%4t#2olTy}+%^n_$VIddUz}2}l7zX(h$szXu$(eL`kxIc zaH@KyrwJLS2>Kj>I*eY1*VT^07Vq=q45dwI;s=TKEDK)0HqUI(Pp;JXov^i0`=Rbf zPcNsuMO6bYJ~+K0lt{ z`*dGCyZ5@iYrA;v^>q0((>%2IPD2c{H}H) z01evjW$VjHnHoGorbFn(bj$JjwC%cpQ+8kgx^L`$F|rIfNO|%?!O7j6`0neP7-c9aiywc6|A^ILT3!(58@`>@Dj`yI0{{O0CTrP1OnhmK zEK8VgQz>g5BeP^*^vl`23qTOJZSx2z;eyWbCx0}~Z!fTsschIoL2M9%3S5*tqST)d zn3u%LglL@IsX!sW^xdlxnWudcgX4tdRjX`sU&hhy!5AZUc33Jgp?njoCPV@DY{hn0 zHPYcYSWx?`Fokh4h6VcrLm#%Cdf_>rSB8t>VN;X!8wp^AU6yeif8UPtJsLN! zUY+bQsup|WwvOG>11H{5Lh?9_N*rku%j04ga{McdH|fYWBII6*8t)Hy#EUVB4I+C~ zvSpAMbB=xHIzb$at1e=y)?^mGpU9XvytZBtu2*FBv8S|nYk4+T>l^m<;tR~y*HS(d zZmlClEk1(X{QsA+^8ML$o#FI<(zw51;aOB4iniQc2z4Ymgx7q8hN?bfy~(??J{RmX zd9`(6_zw`<_wEOwCm(hu=V^*Ds3;i$23rS7I3#x1>Gl}YCu_&pObJ$&f&|-xZp>@l@XI^W8 z(`Yr)zDW3)>&CIqpLgZkhH4d2H8V{B@ii9hJ7YC5otc3>vhJ5C#HHO;pPJOhSqmknj$ww~x-W#EI_l#lFNWj0`GG6p|mq zYK+FMMygrI{~Z^Rp%p03PFN+SiMP$xe6GwbS4Da3L3lxyad#-QrD_9PPu8-1=k_YbQ84Eil%swMzVN)?QS@lM4EA z8kt6KgURhBdos3fZ4N~~m_T}tv+cVp^;T}5ylWoMFZ6s~aOz1-;jK>(vA<*s6$=UU zq)J+~4GmV`7$(Q9&Ke6+?u@8 z@@0U>VKzQ9QzogNg!mi!ok_d_Q!8G2+d<91@CEO$^EAP!i=d2hOr>!BdR&&!J;dM2 zYofF$$n1tf$B*8?8XT#ZgH z{lhyO^2(CG8>#LobufeC+K?kbsr-PZ3@pMij09rK6biEWKg4oI#F~-7wVNN;rt%$y z_FU1jjy-GliYdemOtYyYpjW%~OByob`gU`S%kCVc;GdPuRXoO1WUTXvIhgKC#0By2 zlAuQ&etDXKwt)WvjTg^uc+92(QFd9p==45RABxT?^nW>piTWddR8HaNffLtGUrxRG z^b~=D^G!FGukl)od)3~8zJi0v=Y|iz9~SoEL!3egb({PTX)tMb^7GVz5T0@>bigYp zJPbCn>rS2!2~aon2Y{jIoDd+`LRx>P9d`f<8_`8j)n^1?_Yo5=a6QAoMCbu_h=Z5{ zF+rvVYEsF0$beJPf!ZRf`A^gp{7`K0KpIN|b3RvcnHz#N&;1Jrm5d%Pz66`geh;uB z>Ibps-ZT*ov|z+!G~d`*VRe{iySXw{&dl7voY;e5fAaX_gPUhHyTRs|15isyc@eKz zl24IYn)u-Ab^OgPtx&shB^6m;If!FI=+(#y{T-rb`aJ-2XY((rb6G@eEij(qqlSFIsIGKIPSr#(g4m?o9)22Y`rBasN%P`Y>2Z0 zd}}WH*Uy2C9+)P==f!Y?BX4mH&kh;ErAvzgXagbiVg9W4Kx{HJNq|*=78K5cOOHi> z{XQquloymIh(@$KN8Dr%4lXV>70+urSgo0c%T-!1NcMAVL&qn!V@>D51%y8W_$U#? zSxg2jdgC=ck=+~`0y*vJMI}kM4rFtW+u9soGY+Bk6k6Wv(&p?Q{hzH1S0^%+@-vj` z5~JTSHa8_;zZj4I$LjnsUy-51>J74gHY%xwE-bYyL@PqzIKJNe{fp9*k=Jk1*UNog zgVqk0e||C`OUMYd%loZc80>W&<#78|e~K&WbYP|A?aYYPg2~8NiR8-{clKTnQmWW} zgg?bEWHA*}7UBL`gXRm27-2FjU_6R)QB`>a=%uT7&b4n80ajUk@=j$!t9{OWBLUtFn-e+N`=_|P2(ucka5Ne{0n%@3TgTd+Dc3^6tOg!|Ai@L7N#6st$Ggk^h`=kG!bnLwB3z9}D5k*W3J6 zei_|goEH#sHqdz&Hp3{1ca|8V~iat3l>-tKxI zs|$b%VF@I&4h{~Y)+vENk?lxySypd%vX}nje5#sIIaQd|AR&>Kj#&Z-OzzR{ko`=t zzY(hCN&rMfl*o(pD;BuQ{j~C=Ib~nhZO_(>OXun1Ec<;*qmMcodqG-w51)vKz8<=t zwTbAQ8^7@c+1@v28O|HHbHgKo*o-_PE94}M@WdiQ*m&9-&=aoJ;Qg*ifF159EP?9rV;e_ zGT$zZm#LD7f2>-Tl0Q{p->< zYhkGUQv74RT+?Mj%kXvg;KjOA_e$_Vjl1mZmQrrjcH>^h_S>b_Tr8nnKkp}=0Ji6c zibb|)&BBY{dJdLI=_nOmOPevcOIpEPUFh=@fN5+v;gMLRWnrWk*ij<3ap=+_MH68g zXmMf-^nEU6b;fEWC4lg0>l~W8S<|DI4DGeZUH9YZ?!>Cu1kIr4uKUO^`hcg!18X|^S26i+vG9%TZiJ{T0gR-k$hktv{ zHyokleA@~p5rS{1d@@OX?37b`7EK=X_^oNRneo$w_P4VR9GS)x71kJhrB6#9&c88m zH~jNYb8``6wY$w3{F#32lOvb9lE%Vkey`Y#8JeoyDxS_**X}O(1dVX@^``^TuCtl$ zL7$`C(|84lyRQ5H?6N0FtWfQl;CE2KKTf%`>hA!!wwO3&HxiTT3#)`+9pLlRTU02) z#0x3tAlz;#lPW4>B|r(QZ=8;S(`dYK=V4l~NQR&96GH?+QXeg%55>(zP=}i^wWTUc zs}cl_8A}12mzM&Bo~DjgM2Q<1PKQK`gyEy(g$INYq&R-lo@k-KLl2x-^l{H4GMiEq zp&>L4M4C#*Fc8BK&khfuF3E;5{?qe8L96*8zWk&$`G?Sx4AA+mwA1`m7_HPG`#z+0q9CEwv!Q7I# z-9H%HLqkKb(sb=Y0#knsfxu8!QdUcI7F`ltFl7DALJRlRSdX&{z3#8|{Hj>9vO;~+u^GgIL{OT&I_Ny`yg0U!|>gdHOk zlSDMAHG}V2CMyj+t0=S8v9{ z^^@pY?2tODeFzWZP5(_~ZH&5_=Feq$S%QAq#mE`|wR%MM{AUM++!NL`Hm>y0)Ju}&D-F$> z=nXZU=!3XX-zD*H*hH*q82Dn)uI=IrDAFv#dsto@gdN!;73>meOvZzjl>Q-YUaHOI zR4U7@lx{ihY=lDVi-U0Kat4itEt~GrUxJzF&c;+*#Q+w2w3YJ(r!ZdI2x*C>j)X-14j!MD*K*?F^!i`l8L zX`-rqo^^eLuWRLHm$ud2pMH3*x1z8Gw=2JMYoFqdHqsY+3lY$~&ckL37oeqh+8&H3 z24CBDG=Y$1n+#%!0WmcN7Uh%Tyc#m2>|%aiLR0)+lEh^Uo1ER5B0Z@&O|(yb@j-o9 zM^)&~$j#Iie<6|0T}exPuiTNsTw_@3J+Jj^1Utj+bgS*)20;AKV2zac?oC{e8(6K+ zLQQKRTKJ^m4sK%=^)-6Y?eLiHZPm&-T9;KTm)rDRWO8%ur zv0jD#DDvayPqRUPlq{oh*h0q65iY|P{hst`%jX~=M|&Vc;R`OBSGJQ=xa`*>WgNeS z5_B(%UrEjVWj7LS{q5UHYXe52$@Y5d3d#AUGE{Prs|S_0gRF&at~sOI9dcsGE#-R69J*|0D|ZJA!L0#3*~%4~_~SOzBHHH6dCFss z?Lzi^y7S$|987|&zadAVRF@@R2R>0{597bmoJlWgv04Bp*S7Y+BP3EG*TWB`+f2h= z&xq`=IQ2K+QYMVc=Hw0eIy1eaZmj5&$x<5;gi%9Im`Xx4!@!~BU<3(Hco49fv|sb5 z8=ArhI!3ye{zO2Z*==;*d}iYPSSQDHmA?{$>P5X9b!Z9K{<>2CVmHhZbU&chKOZ7rW(_EsiD)m3*Lb6BmtuTp;>+neCFDec`eCjl4tu?OP{LpO?^5>Vg!)v2^o^t(+l$7dpC+=5Ak3!qU zqcrW)HveokTT}E^Z|H+!p-dR@+dt@{%_t|k9$OrM-F=H2@uh*FdsCib+Aesgv9 zl!sS_ZIf7Bv7WA+U_WjFz5pu@QHU6-%r5(Y%M-$6-oQH)OUrFL*4E-rJ=%|z86b)Y zk<6$3Z&5&CUA3X45APJ*c4A&3-hrJBk|*S=yQ2p^+wA;X>)Ro>aI12GB(PYL77^pD zU1PA7P=+j>7BjVOv|o6-V0zIk*k(7TgDSeevMI-JQW9I0Sch zcXxLP?jAe=g1buyfiOGy_Uw=Cb9(;I?We1+)UBdm6Tr*Q)2pfA)^n~yBCK;uN;>Si zq(@2+Xb&`Av4XbY?D-of6g9{O-j0|Qo~n5~UwzdwAkKbL%muC|*LGe%C^ne%r?O$- zrsIe#M^%TWqL>M=LvX5pD_T1Y5K@1e{{6Xu6a{2SRU9m-vY7gKrp`&Vx7DDF?cvjk za)+r?yqIUsMnR5bp-yGMoSrOD2jy&)YR%RoTLc}Fq3DrR?MaG7c>8lRlhN;DnDS8* zvbcT5Tq$sr^x5?9C@up7OXy1(aM7f_KDO2*19zN%Mx*<=?VzG6$|v zF&<6C=f6G%9h8_{&-z_<9qPvL6Kh9r>Hj^cX#d;GcU9|oycN^#D9RQ0bR!=+aFUZl ztspvw1|4VA$OehHn8BDI5CTXr2&^qkcj;N$36j~dzbhx6(!K~FN{Y^@=25Vmrm>1C ze&Xl4cEcOJGJS9zzAev`wYH&^BqnrDSN=%7gN@=rU0rN?W~&nkOF=<}R)qR#2?uo{ z(YnYG$PRKFvxE}zG(e)d4{p{@8r;jzvG5~*DuM?6ge;A}h%peSs}LM66R=x}6>l{_ z&vlhAydI4W?2jkEO}L0I$(Q z*S><7q835grWy%6xd;TeYi+G>63MDj=5n>ld9A%V`ASIUHL#p{;p0+f^;pwVy~C=z zwjbq43mE8e;_#C}PBYX#re1VO!0EjoHkTAR>50j>GatiO8diT7lI>{Hgwf<+_ZPMr zI<$|Lw%k0F(Q2T4g9X-w<*QvL7?-U6awh4s(H3KCQ?EJI*vSOb|1zC$_OnSF?X~8!c4zzB^B`+c5E>ahPO$5mHh+WPvX;1xi4%^;3l9V=kp#)+mde#FK9Df4 z#DrxFN}{y54&K=(+jj8%1BJlEUtP}2aF`ZudktVyt4k-t^a-fzL;Of`cXcpS;Jqek zOm7T%fDJ#&^Nwt9u5zOCm7R=S%z&?D!Ss+3^;R0eM z5@B@Ny`8NeiRyT9)?fU%=`w*&-&rbYEG=7LiswyU3t5$EtghTe=ufw3aSp@SO#8?(}w&)2qaHmya?h*VT6 zA6;j&v|`SQX2zONLZ5y0n|4QI4D69g?BueFd`vxX@R@}P>CuKy2@|G`^p%49aZ~HO zk?QZoIr`IAM$nn=({*p$kg-;*-)a}}qh^e7x&;8mgS$38(uQ|INlf$mk zenO$^9W+l!W&5Bjo=iYDA$>**1(|CKYd-WQUMZAzF|H`B#&i8DJvpED@8263 z>66f3XdBg;bcPA!4Y*HquK~L)yxL@qe*SU^f~AG4H<6n&GZV3nV)HB?lPe(HQeW?K z&O%a+pXYCA&b4_h|ah9 zTZTSg(=)bpFs5OxGtx3slYdxTu_>OX6KfP#lnp`VL;O@ z{yfbPjo+O*!9XL$a(>rmuO)DCT4aJc^Q_lhrqtAvE5~WE{@U0v(okQkGb?@Ipr7W{ zE9$FPYek2f7qRhSmF`FHxVz6RFPfVynsgy}^xCyOD zrFb3WU?nW%y`|NHH_Gz?;Yc&eM1dZoDjv*Swe~BrT9>*^BQZt6J#JKkwLFxpxmq`i zypM;XM%Pn^lQlmz0#?nm!+<&KYoDltu`YQQZcJiTVk$w53zB}%FhER6fIfpDFXr@j zMnqGN*jpo2lgWqhZ-%C6a_osy$^UbG=*0A#bX$h|WZ|-(NMdSt=|s}rtMU&NTsrMm zE1SDC_YR57w5M0MB3??;?GtFuUqEGac7dtp(+VT&UzZBobw3|DOL#Mu%pST7v2xFE z<6#CibD9{2ulNP_UnCj7Z2lZD@mZh zCyiISM3GoK*JDggj zk>bD0p`F_w;)@wQ2wUn=q~a;01F(I_8>Ulp8SAs9Am;Tw2dZ2>NI8Md_S0pbEt~}j zf6ZPMMa->XI3K5P_PrbTlRIO5GY{8fB4sptEfdxq-jLND`J_dVls(n z@jNPpTNr1KaKlwh%Fr7T=FXpik0p`$05_8AZDSR@0aNS=XXP*4R!NwR5iA*nlzI@# z1tvcH9~*^+OnHQMLf8JFsIc}){q8$tVui1Wm_JT`K!@ zAIa{ygDmAt_V@k5ICtul@rO`_s7gtw^E#|$KquusO%~B9)Pl|l?N4!?x}(RsG7>74 zcsmIYIHEyYHImWou=czF3;Nq3`(wm=hM+Crjj{2k!8O6okWa7GBkKw7GS8f~X%-gK zAw*a|yH|^WuCnOsi^H?$PpMTLcmlDUL27u(C@dlxXy4J4&O%L%2kME#YksSa9r1{A0|MWC>d3>Y_=qEZGz%LXwxhVIj3b( zpIoijIDTL=RL2Y(f2^7GJ+n$zlG4X>7~RJFBqo)26tXt>qTZ;}NsAHADVJi*zn5D< zxu;!>wC~+>C1=IBQ@&e(T6MygbfkWUZXRY;08HAfhJJQ?zObCSRuhBk!N0ULrq=T| zN@`v9j~8UC{$&bRn7`BA)IxRr+%c1d#O-dJNVfA8(2wFr6nU8>I-9#(vr5@H#xl4K zTYKF{QFe|IOt;OhSdw){cSSiYDSW%sk=H_Nr6;Y@>B_OeupY$4BV?IgUVhQ*on;uXFk{ z8i7jzv&tXSbsOckS6z|*!||%#@wH0Hvq(99*M%$_+UV*;zQRb=E2zKE8-|({uYe6j za15+ITOG|6VutgSuPGt~Gnw#?x@KLdI^c`-3(_9;7$FtGRnXV>x?9TQmr#(^U?YV7 zGA%Bt_%8b$$2|90x7{OQFQ>uLd9zdC_Y3v+W{7Tr>u(mGi`C0>3zB(<_fPeZh*dB0 z>C5dM`5;)S**3i+H2LoS9mR|scEO+$@+g$hph)pJI7A?un)n_vN!Dh2U{)hRVu`L=Yi5cVL0Cvgs8OfZFQ3cBAMHwG%x%_#o zw6}r)$tHaQ0>OxdAV~OlO1i}27e#@j;sa&RT4UYAX;K z8z(W!@R63=6@8lo-&dbdXwuDWQYt1~_FFiA;n;LU9SR3gKK#r^IS4zVJ4UFa`diHc z_Y?So&8KAm24Zj>Xsy+bHTy}4gE0{&%L15c*&w2gK|6hwo^Az*Vx3LLv})?C$;c(h z)?nD8kyA;JPaPQ!4;MQujd06nc2oDPir})#8|&%M56HiJ%M$vuA*z*`Y=HmSsHH}A zRdH6YMb1INh5=zVu`*n)!R}N!aaW*Q$HnMdM;Y?Xp=Fu1t+sm#9>XWMpVbClq@(@2 z=j$EywF|yFC%jK{j#*TTl`0eGeu0atl9Lta%+53s$RR!_h(HIcB5QgQ3{q9ipKjE< zlo`56G?z>GJw@S3+PmSfL7Lf7L$084ysk79twWh97t5yFX_3Bcq3A(up_%qe<6A@Z z2v($tWo#vb)<64Wbcx*U$x(6aa+={&-pcwZ)uTi1j9Uxer~*j({0N(caA9DTlaCKI zu#pw>qtuA#BRQ@lF~_BOhAbEyWX2dHW4k3e(-0+`=|Ogn4=5G04I)_K%;793#l&a~ zcv|j~;i@I-0>e(BT)~EWG*6xe)v!y=If63z)0gWudeMH;W;SgYFAF#y+x(#{%|}Pa zI>yYvyrBX<=lb#A4gWv^>O;@qz6b}^az>l`1AvOLQK2`Ap`TsN{N}5I=@ad~!7`Nl zT=m)Na6>QK>Fk5wwltSnFg$8y)SF|ttfhk~%CVEKDjpTp#}w0~U0D~?5~xGAbu5Bh z=^WmQ4ms={?|lf9CLyw^6eWU$Zj3aW<#D9eZvig8#?w&x&?I1?GJ)n@aht5GZzm&X zdW+8AN~VFt&L6o;{r5CL zp3gBn?;qK#b*GwVzoo|P2X=k{ow|~;AFGSJ$#hib zx3(UMG|JXw+RI;2%+$#GU?1ks0~xP%9Zlovtur!`4S)UBGNGBATg)lx)VgwqeXc`y zJQe|&f4Hc=$Nf(lzV2&af+}rV#>&jXd~uba^v|@lD6ggLcw%fcSs*Gi9HFgkJt8pD zm2B-71?4nJ1@*Xe1~5q64me|%)}VO&r{$R#ZP)hTBu@;&MxQZbeiZ^&0OsIc89b;; zi+jrJc0ax6oj7Lzj*4K7EKwUr6h*3#UNh)P*KjQy$PG~gTi`R~D}XKE6P>;o$lIfA zW$SU66FdZ{+OZ&()SIar<*JV3yv?R+6k+dgX%sf3zNSstsxg1^WN=*4eAOCIlN+6_ z(qTR^_?Fuw8T4{QIi3l+_Fay}2_g9WhdQR)Ebe%M7EN-l;D^?hH|7H-Nk4BF-gC~q zfk1TWEo_~^`s z!T?SHkEbq_l7T7>&_rb}jyB+2iWy-PVY|56)h!RWQp~RX8m%(oh{(@)sHIp@QdjLe zM#4S3nZqKZ<0zWkvc6;fW|3J=LKaq|w`4y_*K(+vx-eUAe~|Y`?2hTc-d;{g;G~G| zaJmZC`aFJS7+6?q3qDeqqVAsS;mZG_S+PnVa}GByhlEoek<-dtjTsSG-f-q4-EnuG zEb=Z@gU9GfrBBXUqjppl5P@R7W#7L2i{F_5p?LY`#NF@j*cyfY_dj)t;Q~Eo9m4nE zOrF`0FgPk;0%atJeAOH+mK}Wd2eMc!EMmA@d>Dc;WpcCEEy8e$9|D51zA1~`-0bHh zp)?$gu9kD*r8OlJ`jZ&OOJh@_AN+pyx>i6Jsi;v+o{V+BDUBzYIsf#^Py3@yZ=Hg_ zk4v*1>?tZ8RxZcnl$fslDVb4`L}_14srUzi9RBDPH7{NQ+=_2W^!=>)?;6!+`lPZy zWYs2mqA`bi=U$9UXQ_{4rrH!t6EPOacZUg0t^Mw5;sBEh{40`u1l&3&xRsWCBIP$CQe>{an z=jyVu7IkmEb{3JAvuheBG430Lx7XK5joGjQZ}C4VS+X>A#6oyJ%X;}!h!*lhmTvaJ zoSdK8I8?1urlZ3ugb*4m=6TvppHTIb{`b0)_RKMJ)pltcOB>&(Rg04B{r=GJg+IWyT`9U6VmD`q;IVLO{LVkE z76q(*tJiN7Z^HW^yN3&BmY)}2$IOny)yd>uKcIcMaE$vP$3@(QZ^BV6H?LZXmngZ9 zU2+#TOAo||gb4%KXbujhQE)H17r~>)kvI|BM(ypTsCL`K6N2tc`>;+2N&0FoddQ7y z|BieihtIRQ38}3vY668IxSRc0&GvwWid|VKUKy5v6BlZ4O&KV2g~UekI!R&?gICcR z*>PE^=G{rles^VZkM4?KvoYhR?7LR0q@D8|A8jiA9s2M+#*97ALz8TZ&|a|%h1YfE z^Wwb>?WS(3<5Y&uoI~vze@O?&v2B72jeu7DoHEi-LH9_w2rG1Cn>qHQ_G7Cx&`5H5 zv$5X7BivT46|rZ&nN;j|+O8ThP6eU?fsUlyGIHT4tHw)-GKIXbo6?BQ0Tx_n@G%8# z7Cgw5gDF_zbMg4?@n8TZh7oopi5#}13xTgOVH>;w3w*|WW;atZM-?Ncx#VS;o}&_n zF3F8Nw`Dt8SR=yDUVRrvnk}6)A&Qu;0olhjBt$;ibeEzse-q}WX1*~w%7|cIbbOz~ zQpD(K*gFKF*_O6+Ot@kaR@zO&dBM08@1!7C3RE-iILexrgsSt26F4_Pg^o-C0+(!s zx_U--%ocgg^qAdIJ!%aiwrZBq+-EdH9ef8k$*i$cAG6kYbN5&0ylR|#ACAOT z5N9ZY_;+5~_st%vBU4Wn(6eq8Os9PEgXqhcvMg0G^rIvz(BaD;`plAsgX2(x>tvuy zX#f&rm}C1;#w?5QUb`=Vbafc8?$CGA@hJ9tNFrR z(nRg!o8>sZEC*{hG4dTKecsDdC$rCw0uv{5O(OP#Z!_s$ru(xek3cmry-r%@8M6)B zXFJ=y2_z$35T|8}Nbr}M8|H3z;eUk2lf>sRBjtZu&abn2P3{6t6zHye__IOqFwGVJ z6dH-Z*Zl2%g^)S>%LC{n9r9~Jioq84{Z~~I-Zxr!DtGwyIox!vo596t)sP}hNn2F_ z(W7~>xJ%yG;o?lFL?j+bI-DdT5iLntt`jK&Wzlj7cMxX|Tu2wkj69tt58xxc_nL$@ zKo%|QmA~Q81C-aXN=y`DmViSIlMoY<)gtq)mS`5kByFt7Ur%b~7#pzpJtPnGSy#im z6a)ffs(imRb2$(;`kb*vK$d$`7Vs2!RM$;;xRRPk>WYJ2P3!l-lF^GrbKc}aSM}qS z)GT?DEtZk>%!^Gse683Qq*vTNOM?>?e?h>{&kZiWGE>%Ye|Brl5ID-fHJtgcdDiQ# z?1X>YrthxDHF&K*%F(JO@Gefmlms9dY(r0C1rVpFfFTxfu`DB^6hfgx7!EgcT|_k{ zD#Ce<2IM5U9+kSH-_FDsP?lIm&^G~+;Ngs;QBeU=DVre*M!ToP%O#Dm0&7@{o4AM= ziLuR!i+_#z;Ad> *Y=;GBB;<#>717E8>Ugt63*VB~_osdqE4iiVA%#pE+fkgnVR zN}u5r!S9~5s(VTj;x8a#Y`=!5i|Ein5S^4XV1~_IW>-w+iT<3to`Vt3j)35I)XZ$q z0GG}bKC$nLX4K1R%*q}&?O-7hKmG8~mhqZ-1iq@(;-A5<_KD}+xgc{}8(?!cyt%m6 z`w96E63`eysFVJ8j)78kc>4ps{gwx!pghyQh)FqSK+LO?e^$TFeo=&4g?4ZfzCd%Ii*(z#y`g zvP)1UP!kSX!iB*`0JEw|4*ZLlo;Uw+MZt`x;?0M{AxM3O30BE6z4$#0RF`={!1hv~ zXQ!$NWUz4FkI14zr<&z}38NgERIhH%WI{+;{YIkDt*;>o9}-CKJc2Xbf+BswGp=VD zfMGebx_djOQshc#_9}t%k(L>S+Nz$l-8v#@dtT#bhVJl~-~DSqe{RidGm=qpHSAr5 zIarBD@Jo@NU&aD1iut(OFIcbqD95xOd(@2|{{`w-c5bhCF1!i;dbr_U0RGqIMu;16 zc)N48EX7%U@=Y(VqpgPvGGSAWmn?|KCZX^$fOXK%9S8O}cija#&m5(;H|+GsMHqzj zvWmiqPsPIsR!ujjNuk8@%jXnjH5ukth(^#-E-@zIBf|m?V+rtp${54D^6`|-F4|aA z;wEsIr36?wW-uIZ9A+aki#&_z<23(kDFA?}NvaWE;xOU&sFd@E0J6;y)qe_&Mgr&m zXbQF)h}e}=k;Hts^5510@_a*Zw8%0aounQa*)kn{7L*={k^#GFq%EANvsF`>N&@}g zp7R(nKF~G^hRUT}z~k5r%3wv5b23g<4zNo}1spC2hEY3YT=uDkRG~`uv>j5n5vFUm z+jF!m-pB31poK$f`H~o ze3JjZuAAt*610B&u2f}h%&`5OAeIcya8FSAHrbJ*?8Cd9UN)nvRG!?ZqrB!xHP!V& zjn@k;beT;kY$EfhUajMs zPg}8|-p$uDx&Or+Y}_J8|FkE=V!ndcBKIa7*J5q(iQ9aR=gnLPZw+%9Jv*5GwtUz~ z@^V(cTl7bA4cKX`q8&!2CDv&At7iW6_PM@2&Y8C6#?N-<`4m6hy#oA~uwF9z`;O+? zKA*eX&6Nc*w`rqU;qdRdNB;c3>YmBn-pPmOUNf04_5V0{`7!6$zmCTQ3JW}V29nwD zoGj}tV4S#%dj2{$neeK&2t@sZ6-h4*d#QTNGi|hUV$bP0k`u;*ZGlb3bz8*MQi_9a zgN}XTfT8giqt>QoT90mi%Eqv!e%=n&UGYT8_^3BtFJE}!)|lVQnmnf+HQ&?Tprla3 zzU{}AEgdtaZ=m7v%+`+c$I*hhQ&4}UxAVTXN6(>BtL96f1+!j$!1+T9sZPslU-iz~ ziH8oT^;lrf9z<{3GQ;+Kq4og0uz2})lwh)bL$Yb5+_1L(kly**#^y$O#tytOp4)X| zgMO6gxTx_!V$hb+d=2rP(YkmrNibMzhFlx1dFyWot;VTlMreHf1Lhogyg<$RaH`*|@^kXGG6hfH4lzZU z7BE(8x$~!c+Rfd&l)f0AxW0k*65iK{jGJp7A77rmuXjXd0-d(|AzULl?riQD8b3NS9^P*t{X3BM--99WuqRhnzgeW-qlHC(LOT9f zM9MGVS5Sen{DFpWBuH_zI6&+!l^-hX|MQIV1t2cis)xG+VE5yNR2xhIwjH?Q#9KiK z$U~=6!bvdbMxo-Gqd;UXIar#YQlk#vfsH<+ngs#21A!m|AOGM;%_I$85H-s%H{3N! z{D0V9vJdqif=oK!;V!>gJDKgJY4)4@31LXAY)buB|LA1V&Gy-?=VKu=X-22M5%G-X zQ)}}qJ#QokS_Ud{O!RgepypIZcwN~z3;P^o=q?3Or>*CT*UkFg4<-^ z<5Ll05L)E1a0G7weJAa4R>WSUS#%LfXt2v-krh!5BQ|Z2M3AW*vKcZw8GM#536Xl- zpt1P6BswP?mlQ7?@-3NMG2M>RXV@SEcuK@CY@(ssDmi) zW!d}btXSe;qQ3;I(d{i&972j9v`@NPNhVsqN6xgO{Tb-c)+!eZ>Q_xyzAsyT>_YbD zGhU=xyJE1s*v_x|!Jj%J4{Fbmvcva1QmsNXGRM|de|1)a3%)R58b%q%&^XtJK|MZgHIooDdUO>Jl0!)+4^sk0K3D&0Bl&;O7qF)R()asAR9Ji0tb zVJ~A{1GmN)E@y$t%S7yb7QapucJ=WD!#DU-VZ3pZ1Q_XQ%8!MAFUwr|_>h;K7kF0I zl-pkRX^!;zQPP-xM46xMOOd?6ML5X1ZdR0KI46)*{W-%&?N9nA0nL_4YeAZ5eJ`+v zVma@NgiN=xLpiV5wtmZumz`Z}r`uD`+qM@oc{fG6be0EeJUGXut*!rB%i$oy1oCA6 zck5}^=g&;;+iT;$2)?d!lC^*8b=Ts;tK!u36iV0P7Wd>x&LYrJ%EW^KoJEKO;0ZK1 zT#V)5it=URkYHms5D@^H(j{)G0?;Z#?x76m#s20nz+91zjQ@d+!yGYTSl5k~DC}Ea zCDs7=Tgw*y%GAE&e)}LYiYd<=EvQQf3x9roXk-KVZ z7kCN7@!V7@12+~;ERjoekGr@rhO<%}U8jGU0#u;cBw`8C3jo8osLwIK3!q3LRv?}N z00ARR9|b94ayN1r`*ww{%6X_?SxW*r@~?6>o`H?Zzjg@jr|lrYTLhUTq5CeQY-J^W zX?KLyPg!%h{58g}0SkT;|NR85_A30HIl7B@SG`mQU#o5Lrw2Gi5`QmDf9rG#G)XX- zg}lrVKZ`)gy%5NCn6LD?ocUs8hM%aFc6|=m{vpF})&r_t_R?_O?$E1giNa%1wdGc$ zLc<7TGz5wx&2qy=O5!^shK}$%PpC|%3?K_zWXXS zbinxRx^627!gsF@$cxT28`?2kE}eYrCVy+WOkwzh-AEGK=N2tG^XS>>X%HtYV;$4D zIgrl4oA%4+0^^26Pvq^Z*-2g`BgkOY=={z43zQ4Ty0Bw1e`28sWC|bJWmFQgh0rL;Q$SAmB^cuHhyo7G(?E27)RnQlutA z8L~il@F>w_1AEw__CcMng>61PvX2nyX-U*>5-34J+#^lawom*cPedYIj$m-+*tq!E zAXAvQ2QJ;cX`Xl%W$9retrEI?$mt7vsng(d>Ct`U?wANey#qc&V%G(U zxore$r`37{5+OEILw%MBvtlJnG@8B;b!9std51@W8c%us>-tpvjjyL9x_LYnh#s}j zKtN9iWDZ%-Xw8ISGGt%`IRXIqxZ;~dn_;0QUiEpqA@xIQXfmU|1;+*tau8(~YgQH( zaA~=pSuIWhuFL?40A%1CB=|}wBm^AMMxJH21?^>oPci`7%+z3X2%6ZaGjWoPcWL)K zi1*~Mu---#(J~|^fprws)Z9{6oM{XySVL`KxukEfmMrRwOfKDbOmVh{7;^h$^dqNB zRFmYTIf51RNZ~G?=u0yUsPG=kETp)zG4zMYhFzvp#MxMGY@br7Pbh6ExVY5hxw$Tw zXh{l^pRHwJkxlie5xD3D2%J7u)MqPr85A4wY%6fpZ*H@hh=uaR5E7&HWc~}llMVzj z6Gpb}&h6%EVmbnc4*+diW)C$}BeI zouHpnP3@4N1|=M}Xvmd=&{Ef7uwC&VC{P3;4LhnQKouI_pdHwMpb&ngN<0gI$Lc>D z5e$NI+NbYTN7J-^+pHQ;i&Zh+2JI@3x1D#ja)>b1e-D<;s@+1i;w-$h`+-~YHgbp0 z7vK4`tE1(tBxjnwcec%^$U)LZ#9O6?=`Fnw1t zcr|fbm$*TjM7V4^C(t_~Q3Mlw7Of!Azh^lPQTI`_jXR!PUWUZ)Q)K#dGw)h5ZYtjs z8S}@@AHhavaNRX+_h;_9j{6HU?|CydGB29_*ij?tuI=f0y+72V&q);i=5%uAZCA~P zkmtLU^YU7dUvzN4b>~NaJ#fm&*wOu7(F?rhR>aO&RNt9-ju-oH-mClOW#Fy#4btV_ z_crjZ5m!N6Z_gU|UhB<6Eee4|?sfk67m&8l@1|D!k}W#L0+*N z(qRqYJWUd7S=Az(+FJ`po>7~^Q*?d( z9|cu~nSThe(?*(o{I+ppravGyP3_2W{pUoIs9|RATV8eTnmwb61_+-;u(vfe!-(4f+X6OUmcIUI#qi;^=e_X4|&{p({9b925O(M9z@^7EGWo1oWa9 zV9HvpX?M2z{e6;|+0}Nh6gNALi$$=?a6}Rg%!ZCd@_`k3P>vA+dJy(Z@nE<0^jj4o z0Ccme9#$C3C>Z~mBp z&>a7}x3&I)5Arq3n(l(G<&BW0sqh+`7-t@)4bW|MxRtzU+ivrS{k81x9_U~01|3=MibDlyeAjtJf%0Mh;5Z9*+f^m^Bm3lx6M$FTQbOoRV;&z=R!W$|^SQ=KM?mZLixnr5RVY^X& z#7&S=kXq~{L>YFeVF?wGL2{+H_UnceQ$mcu{pQVN*Y)yQS^V!bG7-<4WQ&N=Zj1-A%)3!8>sWFU8rR z;{>_Eq9Vj1OVUBT?w;^CX3#iD$7$}nu85nfnBhp&>EVwVsa2cAkp(HmqQldb5;EuH zLr0r|#F9kvW!5Um(vv-vbBW1gT*U`8uD3GivEc{OnDia$ImyLv{PH#$lokc%mYST> z4W=gi%6MB{wxO+{mCbWLE<;1>Ss66i7qvxp=%0pvT=w8s&$U(wxA#Sy6lOEEwbths z->dw0ETFlRf0eaU$lQGHHn;n{P7*d|&MFs&!aQH%9GBn7yC@YWOTW0H zr~XY2tl*Ii_NknY3Q5AivE!R2dmlHdX*M7@@W0Aem)=5C^TSE=(a;AssJwbACwQ1^ ze(Sar_ACu2=uGq3sjaRVXt3|#?nE3>6JcPw8Z(Vt{Torr7Bjq7sjJKMr*t((>Dd{> z{*+1;9n_(v44%J>Y+2>iHx$hCB#A6FOm{Zf`SR5N9$0uZu)zAD3w_pm^?HcfY&vDTZZ%y5rS)?W?84lK_;0(^%PZ4u+@F(@h_( z=FkU0H7g9$9zam#sf=f(9;L?#6XB! z3Jd_C^x2vx+EP>mmYWRfIcRP#2led2!FGY&Eej7;o07^PF;`_qfP?D8Ft@6~0O)0G zikqVp>M#!pz(Un!vEbmS$Mt`pKpljP;-`@S?J2yn>j%%90w`hWR0XGk;88|vkoYM9 zMSMzo^J1|r$uEb>ECwlVGukYFaWX~YYBMSLQQP#e3FCl2cux~Y%Z#?|og6}t8d2g^ zd(ZS=)yGWymNq==cV>IjlE2^SPS7p833zfceJ*{jEL3{7Zty?(75Ks6`ssBCJL2zS zF!{52iW6Cy^l@*v{hv3Nb-#kwo%LfPduYcbf<ac~|D0d$>eo7zx9mSz^l~-Mkh(nu0qBW{iTyF)@U#38-C&cm!jFmI zlab+IWvbv1P=itq8_TVu8xDUt$g!C$LAhrDYD96+ag>(1=qR;{nTs|;PCHU^B|BY3 ze>PBU*FK$+I6|S?3gzNzzSZ2L;!04x^XsQ>oJXDdw(jW&{goOS^{ZJ*g(R^Pa}Cdp zIKR~9KYxZBc{gM1SiR@yxmVb@TZzhDs+`qE@cJeKW^xZ97h)%kkYOscKtarI0-F2i zXe0gu125jX-k%ErH(qrdBN#TH7>D~2bzF)%rO=gE(q_MOzP`0*J_JJY{|mew5q0-D zDG2<(^2L$u20~5;`fGRnO2_0;;s7Z|wh5VWJ#AuJN_%hH*1RH;ugHKI2V0KYB32H( zx#Hf*NAyM5Ni-rjB6uVuvXAC(oTgzgnE)Xe=ivw#TYxK!O?U%h7R@c4+8PnEXi@+E zA_?*W5lJTEWZoD@EIOwH-KBKK=ux^#P4yPNu2Hm6?n-ad9;3Hc2N0A(Br}O=9lBr7IFEk5INuy5P@(WqVB))F`Doj`DKeB&qRvv)Ru zK&H>~c+`2aXR-N}v&Hwt0Tw)!oVy2FlW?fykhAW1L{h3I9$f)4c&_72bY`sU=AUI> zaHtLW0O)34m;gUVj({BggIj}W04K^BagaD3jI;O#B@c{ncuc5Yq%{2y1`Z4zwE|^H z5W&zmLkW>WhQe?1s@r4=XJp$(jU%z!qkn#YcdIJ&odw0yL$>70S$9xk!KnuCiVJssU+*IMKOpO&2+ zvvvzbAWfCNBhvza#(|j6lRed>ANL!9Xl3 zV)X1hY61XAR#yq>BfsMun6e@qokW^abJx?YLx)+)#Wx(8)%{PK)`h~P&+WHIBmt=r zL1Ycmk1Moe{S&@W#!_a~q=9wFtnLj}tm9a6K&8`V{d<~Xx;|*sWb(MshS*E1;d1C5W(4EMg1 zhkzYUVy9Q`1c4)y^zQBVGq)L#2lKI>*WCi-Y2gNP)Yme?KEwY0%xW{Qy{2cczgnMi zv!eXpThU-CoooOl03|W{*bp|a+#8Iww~Zbl4TB&)*<`+prOU?SB57_~;mh8XzGY-u zlcFWAM!e=Y6w1qU_$)H0{++!8c`Nx;lZpCQk?%M2ZykG>gEPFIEt93)co;YjhViv% zVSIcoKeUFT`1pM9g;+h(TJ&JYEPAWM!3qKdedcQ9i4tm_2y6kq5D7tr>Q@bqqqHQg z*t9i{YTuFlBWa^aFUG4KGcTbZ{lA<}NROrsuhlghDFcd_L~&mwSR#tIFWBCDGyZ!W z5xHGEd)?7l$TUyR&2&9-5O%XRaI0rCgxtIn+h<*PKLh^*a{h&!6hc1^|8~t^>s-qr zKM&L!SpwI*AV*4Je)xFgGGsQ7FqcU~G2*66AEYBA;8C&w0!BkcFpl3rSQp&)7g%## z%dUyz)0gH|oVKW-8da`iMOaRlum%NaNwmHuyQ0d%j-c(L z9oQtB{epG1Y}3{$um!eO?0|L5i}VCK;=ObvL)%Jhrm%-_8BwR5ebT znJdF%=%;k!4o(NJZZwLsPRqaguT|!L@lRF%oK8v6pt4_L5((byR=MFfWDPvZ=>7S2 zdwu)&$ASpUN%)2vx7+oNhE+PeY(`myLF3=Rn?gw9^TP;+?nv&>>#u>3#*=@Z6fe$h zc>@&VM{IaAr2A?z06^TYLmUNxMJq|9h&4&XdX&#u%wUk^B`qy#FP;#Zo?Bxpw|}5O5`@HPp^4!P030fP51!iv6!%ET5koTt-l3|0J%zW7E4U#k zIcNrHGp$B9!T9u*ZM6w?|KWr8ejmSlQ z@g4ok3TBc9k2VtfkA8Jy=Os%UdCam3Yh=1ud1AVMUvGC8<~wpj&VLE`a?oJ0#dQ+M z(tk|49@zKi@#WL`=-0BA5O;KEv40f-rVxx zayE#nI0#=ZNb^ftS~@fkJCB3OW2AAqaZk&GgX17XRUXt&lH6#>><8d=Y#d~5gftpJ zljLYz+W{kP{1I~=I*+Td%4ZMWB~ZU<(0{w9&G`2{U0ZB!t;>Dw*th1$7(4JLm;n=ZcE=yUfJ6Rvg=aiU+pmet~5y<<3Nhk`{klB9JOlgQG>C59kYC;|q_1c<~ zge(0DWR3+yC=3Ds!4Uwe#1vDFWDM?#v_qH>ZYz9#Ko0;J=JdF+ZOj&V0}sm=$01{P zs3T)B?FWafaXCXm?uu7({+ueCtTO_y^o7C;-o^XKUd4x8xy!}F#8F^(8u41C+vS1; zo4eBmwY#2CgC_FDFeBrc*{^0;WB>hUyPpi$+lNx>3M;qx8`j%d^FE#wg~f5Q%qAUc zX(0|7S?2Wb=zxj<+;pwzOt?H_tw2azG~Oo_q{c}34euJ zR)B9fX9glfX1a|g0{a5*CZ6hgAp;P|g#Y@x-rn2;A2iJ@f8feafGBm>L$HH6@n1b_ys<35fLXix(qUVv<-nxT^hzzW7~ zuH<=yw?0Bs`SPKb_C%zuvd+A2LTXa@s?yTr8#de zP?5!`HrQYpg~D*T$PQ(Ld6-7YVv){Eru^%qCwSbE_A-d>df0Grv2PuC6R@f?aCpUo z6Szp^7&l_cIpn^I%UdpLXk?;Q&MMNi%`m1-mk*Pe3MC6TlvWZ%r^pu>b4l2e6optL z6BEpoA6V6`!r@pcrL6b}DNRe{RIt~7-de(`VX3CIm!Ydp-X>@8bvie&mq7Tulk=s& zC-F~;Iw%E{at`g#K(5wbssONNljEjx5q6u@7@)L z`q5e+F_{$1MT8l^(}ZSBi>RhiR9 z?O{3$rSH8`|K)$zZ@f$q_Ni9@%hkB2vp-xNfWZ|+X7Uj{ITg{OE^AuPP&JdkyuM!y{JeR7SOD@uUQV{5ABchg=#SvS zPIU{UPEL~hLL8R7&f`~wn6&k<_+pT%w;`T4OjJ;ir8*aclgKPd;!0Ies*Nu=j4c=+ zu1R^y6w&lJLHrnL7r`Y1I|(}ZkR4VKmOj+{AnC~}{W}?L;}W-}#QRV{RPvT%1X%#~ zw*-5fnFwP-`N|yHQCTvu%@qq7nQ&G?y0|)k%S?KueuStWqylF7&& ziBfLXCT@t51M6AlJL+;6+Bc(WaWEeB$lS&>aP(=kyJeUTOvRO7=nyHg*xmRQ1BOlb zchnHY2sa%&m3Mw&oP69tqBnwTu*t7&uae@)_%ZaFwEgA2T9LT2Td}YHBh}o|Cv`6^ zEB>QpqNxk*l9Fbzzmr!w$va2UvV=DlnOx+6*Z?GFnt4POQz=s!B$Ip;W($L7#6NoCG~NJB8x?%D2_5Ad4;ME!WHFiLu&989-( z8eH;}c)Vzlu!EBOZM18OvYrdEO+lGlaN_8)WuUYn0ee?Nd>ss6#|EX+h?`pj z#~dt^X6dA%=6%*(!e;AaB)y6+*fUd2Uwtqe0!$voTlQ$JD4Shuamap5)r-z4=)bVh z*DUmsu`S8%Wl9l9S(0rdPAaSall!IdQSTGvyo#M;g={U-7qbh)%0bLgG(<$AEF>H&SnzNuR(II)0WMUMH=cs z+7PdXM=G$3{Gnvd}^5>p&?v}OJUK{Muq!M}Rqon^TT*1tf zfzMU-GCv>`*)i>MCDakIb7=kGki9h#T*H676GSoRVp12(;^SivfzGRcs4*FD;ENR1 z5Emf(=$;1kR#TKA1;vaZlnFB~|z^ z>?6&c>Gl_Fwpfs7r_E0)ra6dOFp06Q;aZo?s zIz63jn>)@ReGOi(nx$itK6SZkyW8cn@eMxQ-ND7O|9<*rw5Aute@E(-p?jEkGodF1 zjhCQn_A&C~$a7-P%gY(~CJ0Q50d5LF^Ws}rAKp;1rA0?sAnyf+lFAmzznAX2$Q|_bX6r(vDOu&Tr^CN z#KTc#04&jz{s7_;E);~hr3fWF&I>%CwKf5~87B}H;W{e z58rOvzAt;s){_@@m{W`sB`B75+#Fq6`@Q7-tbX*tu+aWlgHPiMYZxPE>Nl<6!0%kA zr`#Obqn;~Tr5NQmcb#?Ea6PYif`hC261hXx;G%2ezheYhcpHDy8rYul`n$5>LLxL? zXYUwZ;fVKfEf$Kj0$?y^YvC=;!yjKD;l*=zaVNH|Y|+^m&N{bI`w@zP`I7;xx6 z3#8bVObHd4CJ5xn(_Ps^=g;0WGwD70NGoVKKdNUs)N9(zbIxgIhcOgz(Cb@4Ao?i% zt29c2NSx?(=iT6YZpNge^wJnFI;}wa!1GH_030v>(M-t~1cZ1_F@9tuI4X92X|Isb zVKLVcl)(?5is0Yb*PgJmn$A#?4JAugA|n}o)pLd6XA21#kwX|7MWTnX4Yi|Y$4wHB z7GP!Aw;m~`1cGIdep$zY;5gaChs_1xLa}Kh#_5{`QL{36@u7lyX)#07WFV=?_ze^; z+9o@yNa^7#Qw?5bg4wxLF3RH;bv4-VretZ*5_@?J|1o?v7#)*d8Bcx*O^pVOoT}{+ zwa6iylGkZ!p&!4{)NRkx)Frmk>m*OV*2Y5Hwv$rRo-;KvJ)1RqD|3QSh9hyt>6h}a zPM=#Ljv(pv47re}FKxc!Hn}xmg4ScFgkTxyFl@89&Fvrd3y1HzWq;Q6V1-#s1 z<)$%BOHaBU6Mp1UvP4xt3Oa_I1tM}KIz2jF4r%J4fcYHwW`;73fK>%A!K5`cF7u~k z{^SxTC0sPse0c=_%BtU-+WphwAG`yTBziV@sDDt_1ojuS-tQjGp+9dclys+=cr`nS zbFx`&_Kw;f9uft5$-ek-3_q@ywh5@F|WeMqz|lB;?ad)zyn5xsU! z(U0AC=}R)u`@*-Ynd=Ypf}|N5EOd=Br+=!;pR%v&KfURh?VfaW69<62sIzrnf**Y@ zef-?t+8~8ouO<^Wr;s;_+6M?^_f3~SBJ4IKqopsnCc_z&D^LNg5cV83EQ+ zdA~BU(_J!=Li`QuK7#1>pHZL-L3~Tn#BisCL3+nz3dI@8^vSdZIzmXEN2)*Z0bs}# zYYX{^4~yCZa%skh9fFi`VEOIG%i!e0_Lnph#10czqYZ5{6Q+(75u|hr zs3w-V^o*v%O}~PlaH+$yvqhYj{+yIt(5Vp6Z!21if)5;9Cy5Bnr4<(Blj-DBsLQr< zO7VIMc;vCOQ{I~`Fei;@NKVqVOXDlV#DUI?a5q;pdg?5V2s~)i19tf|n(f*3UY(YB zmFTw}q$zyVRo;AFjbm|hJ{j@V&hB1oprgkBx?(Tlzlp=qc_(E$d>)pB0E7XEl@@8X zvJ+xem%;+|65wFs7b9Ho4H?3KFv=xLQ{pRxT+zQL6)U6bx>?%gX)xs&TRoz7qa~}$ zox{DAS4vz^2!&FY5a#^CdlrtG3Kfl_YbAx)pKq5=XbcOysN*nBR&obqoePMgN^~`* z+~U3}3t~8AyiQYN3U3)loX3q?a^&2xU#Z0jP7tqFf!t#M94fEvRqOm_c`08=$>p=R zcy5}}Vsc z`vMVKSfvxVgT~n}klkaYf}3hN(`e}j5CD$fU3_R6ONgVf@%mRKb`=|_IxoPqY0nmg z*xE^AXi``55B8)wGft?xB+MoiY@;WMtnUt`)v=T>{Y>uRplM-vR@aGFMtreLw#k@I zRnoV31+U+gcB}3YL-OcVnk8yH-VEDw`Eg1OEqjWU0x2Bl-7bdm0SBvXHEjj~40z*| z>oO7ax6jwz^`5NO4fKh|VADWkd~P0m zxdUAi{;btgX%9eiBItVB@p9PHapFn%-2r2 zV)lUbB*Oh4p%jb^XWTkeoI~OuFb1bAz7F*XoeV;?I&6+$ z>=9D8CTj+=yYKqhXkryNv-r$eCZ@YqWcwRa1_=J00XCt z9u~q7N=q=y9i_{c#4;E^^6NjN06=0*(nNql3a^dRuJd33g|oOeQ5OJqwf$U@F9Zgc z3V>M@Ub>H6uAB%gCLkFLMV7+FKr#e+@$hSbVvp5-Ok|>lmq>y|KGmk+yZ*Eo8?Nf& z)J~gn2MEl7CYq+H!*6&+5QW=qvxS6Btxt~jyX#79kWSG0-Cu;iC;h)Wry(DnK<;ww_eoyq2$gj zvI-rZ=!WZ+D%nLd!ZF#&da&4+TU%et_4xDQn544_6rq+}w zIh8&9RHm&rt$36ZBT1-|=xKDoFucyX@yUb;N&;>w4lL|!PwgsfDS%s|xN8W9}+^bEL%!d`tjw}dX4uywEGGU{}m|fr`|W)az_3S4y-% zwne|yCCQK!qp_^>Zno5L33w(`jQ7rSTZm6Kb%@UIOp;5pRryZr$GDX$6>_%pvs-3L zXLD2N=ZRx&h?bG!t@cYw<$2+`R5Lv5W9k zPT?<1jf!7uq_|-$4s1YEv{?9O6hHtZrvGGHf%mS{LvzCa(g$@Y%NY(|k_i@?J{)Hm zpvBaAm+slHG$194WGNn8)-8ot6FRp< z+|aL^H;Zh3x?1{PW340d(#iGt()!`g3SQ6FHz-rKZ;YcNilJV%+~v{RMMJitLvJ%7 z(9jjK@VE z&7`bmHFxP~$3WG#xm8i_2(wbnJ(&j`qBh*rr@Of}%$riV{eCOY#Hk~L@~jM*=`l*y zV|XU?7zB3gB-}xq^IuT!Du41}x+Vb6(}fIBJ-AUMq7Xq?GY&S0!H!i1D6Fq$AdaoRY=`=>MI$dNJ z6DLg;|D+!_(f%(D3JW;na%D=Kb(&~Vts$@U( zSos3FjGVMmaMt?D;N<9#0xJu5`AHmj5s$deIWVq@I8zy$HHXgreKs+j>%(PfTCSRd zf%;dgD&sg}RdL`k9PuaGU5Gk3XLqMfLn4*8+~{K#AzcRtcy=q@O9?er@93f1UOcUv zwc4(U-8Y=kDWRN;9iR)hL9GryvBhlOWaka3YUT$n20Z<~f_!t>aC1Bzm8+ zeyP_oY*IN}5^>>8K{Sc~o;B>$&g5@GzHk5B#Ain)xd(|d%;P7cIF0-CyBbCD4;TwJ zbsLxM($=MGmqEv*Z{FjVGwvhaPKG<)90|?_`bzoz3fIfWktaQWu5Vu22EIM|_|3mP zyq-cHyTd@>xl0{vpL!!$k}scq~OxX1_D34Ct@{2jI}JS1`8XrcDPRE}Kb8 zbeQ7C*?&fX6o9ytq=n!N09>%5B+m;2$T7tKr4O)>F{UU!OaO-IHc6>et)t{bGDTX% zpaD@aKdK!94LF)g#Pw@7cy;=aTRzcF(1eon=9tdhgno$?2ccBh3YIOd*)@cC&4ekn z9KPg*it%caKk|wuEt1P z9V4_jD9qX1m`57NoEV%M!Be7)r+A@UJ>O80j`vE?28WXxKELX6Mg@ z(e72TF-P`$&-Ait2h*+7J=$Xl)!T`4O7S)ff5=X2fJEAVY;I53EOmNiX!eDv;QFbn zGEo^o_GeoJ?Y+T3-`}O{{f@ehH-dxp);d~M({1Bsa}9AWzU6yTpJPRP306N$x3g4sMfhO4Afm1jInLtRi6;Dui=Uk))iXYU)g_^pr&SGv``E(E_@XO zPz|Oc@aDROz@?22%vQ_V zrZ`7Bzj>Rk2}t%YWJR&UAxVMDpWQp;a3gKPFOwua95XA?(|tG;COo%%jBd~#Ss@@E zau3;yy6SY&ENl-S`)I(|?-H;-%w6kb>)$sfQP;jV-m|$I)IR5Md%j3WJur9XZ_edS zBeUx8<`F#b7QDlim3(G6Ir;OL=8%KY=!(aDa8{?&*}T35dbbe7TE(Y-MNpGx} zs?(PpC38sQ>*d(j|LA@wvDIOh=8hR|a{amuH#LH`?`PeXm8oedncOe{f!w))38BI(#Ml`4nDv$^+icWkmU&DY`1@(% zVb|{S|1%1VAxNgs^uYrF1Ir=k3I!TX-o(`fCPQH7I~o7c6lPg7*q^z6Z|Y#jo^Lh3 zIxJO6E2jQZWb-+(YV=%*RD~vrMV&ovAz!%g_bU!bl3rw->v-$-6XrLjQ&~)U3WR4^ z4)blds(%a3hy)P^zXhx+Y6WE){yF7nAQ@0GX%~P%GJUp#dA2VepBz};AOSOwvulW* z0Q2eh`5oeu7RZU=F66@KL||p4^BUvM`#*HLVJ5iGL-T(1<5riv3c{UkAT1p}`-sSS z-@ts`3_MyMYDZI*I&LLQUSZ#JDZ|M-<Gtx=|MG83yW1APuXp#xrl_p0vaJ z#U)5|9bA0Mt}tXF0GU%7U`&NIDIqhb`Eg9znD`Lz;C*X-+F;T>LEwoykz6iJ73GkJ zWEQYUKx`W|D=<-h&*@hgdR{Y&jCn6N5~H9p(u?(Y<05I38NTWP7v(5ACpex)h6tBh zddP-^np5Tox3}Uw83!M~iCDin1&C1ni*89kX>%yQv%1I8J{ld802ZG*{j6dc5Y3c7 zGGKA7HJF7U0q@Lv-p8c7QTNxLRL8VlObne_5sXiA3! zEx#Arr_@KRJ!)lKl`(0s5#{7e+BN6(wq}&r$1chISQ|NLcW8JELvyjBT*3GlxcY;6 zYjl39#M1Y(fIR!8B+fNnJRKv42kuO>*_%v%#kt;X zrmxRl+JL$2*N9?h_6%o9c?g}Qdyaxbiwez|;Nf6XA9yo<+F3}Kr@Y3%(YC~|Z z5~ZVMYI!V%eG2GIY&4lFB86I|cj}D7bMk%jhC<)bQ*x+pw@P{V?0!sjn&ZnDaaxbb zxtit?Fd*v8206qYJZ?8~YR2RN2!s_7TmHYH8M1sBqYza8S#`I&((_fKlz8sVSm z3qv=?bfwyJfDTUTMg*5K`Df{hMZR15yMErJp5*hBR;yOnnVaNo_U(k*6B(Bmu9qK) z9ARJv8g_10>{lIIj<{wv4*vx8y!u?ID=C^kEm`n+knpit^+8t4-tK}we|+AB1bMVQ z=!Q(SFnYI4cwCaHrt#c3X4Luq?0mqbLs1q?uqOao-l`4tB_;7hX+;w0%{V>k{zj44OI zp2gf!N3!^$-QMNmZGBx|g;`+6jROrQ)1cDFCOZ304kfX&;Kntd)1jH4(w2y0--tCz zZ!MndF9+hw%Y*Lj&#*j?hC~dY$ct54wwG;HeJi(NmL(?mfbK_b`RL|0kyNJGE)YXi`96VPo**f07lv~qXei`#D$oa}HD;!+FJ2Y~PfrrRcP&w1NOk16z{>@g` zLl2Bt;+2zRVb%$6X(iRl`9vpzU?^+VOvy>TX#$#R2I46ruOl=O2CKoTjgjK0q@V!&TD)JxmBp*x0SQTpc(Yi@~|)a+BX z)M&Yp+99yYb6?o;3!hq5)dLYD4V~qpKK+X8{uR@EDvf;@?6%k7e{VN zr@{AJOF`$-JHq3Zr?*d1VnXHg=1{k0JtGsD;o*=5;pU{J)0X7hYvi)vHN`UN=SiHN95HIL?Up-{Hw`Ejs zjbSvSVbd0Zs$4ZEUH&g(rNPrw6k{BT8 z46Ns6yiLlZ(1Y3iw`R~s`@10r5{(iHJ3GOCR#!r;eJrgGk>Z8h=}KLF|EdYnXeRMv z>9wV@p50?jzMYox(!7jS%c7r~RKi^tHYfX+6-w$sCkfB)1i|S-y9***wN0bZ*$>R* zPQcmEjS;1DM|;L8ta`+stv&2mxP)u;OG?}~R?^Rh*(C8E?O0?0?$%So2l`p`bW?a}2Q3(N3Q^)_Hup_R{PfczY>>ERalEO3-<% z`_3abM$nNnSOCFCxJdg1{>VO>ah^~`LT>H)tV;MrE7bdMc`2Lotr_PzHN-jGwZCAi zXY8fuiJ$$_asBpu&0B9|yXK;2PC7`ptN#4_&OcMX%oO7;>2gr6BZ$(r0o?17Xa zvE_5j8CgdoCm-)e#{M0>rBa1Ll1Zk-fjQ^1#)7T_?@6?pjBTwE!d5;Jt1Hu78&0dH zQniTQukvi&X$Es7(O?nFX=-WFvIMK|E0&<9drcEJSGbib488)=!eU1+TgUVA5(594 zpiYIiJ=C9b$2i=d^?dFfK5}->yY%Oy2|Zdc2o`!L))c)GWa3uW-IpPQKHk)6?7PjW z$L#g_unO}Jc{(R6D24ol=-o-|kZxxV#y1`#nAXZD5Z>qVk^UK4x}?MB#NQ>z>EuSh zHJz+{@w!|Uc_}L*^`h0YXJ_a{Sp)LF-R3SGhF3cMPRV?(=Lx-@fBGK3iLB=oG}J(z z{`s1ZCno>6OSU18Xi1u|z6P$xbHt_|XwJmv;_58>PRjx;XG60bU3d#~u1_ZwpF4LA zP8~&drS8Os!0Wl}S<#rx#QKC%#3q(n#HbM=jQv^2=5s4&bXrQq96bBvNUGwb*2ej$ zukMmp&+A}r?5?T#ZT)bR>meSU4;g@M{qHmxLe9c`)bq0H<`{ugPloe_zun{!)lz=| zVGS@250C>1BZ-PIP~slne>NiwS)zGdNXbr-A4|0w2U$q+R5Cbh@S8n>MD7v@?mK|q zVP3H`dg>CJOzPJ>a%v66Q3m3UwcImyd4+2avff5*y4yiPEI~Lg{S&?}HX;odyqPQ+ z(mf(x(s-fUX>oQp`;bx5JwK%Hz9uqaonjsxWnSWV&NpfGsKA+&z{Y=?^tUA zB=4XVJ_f2Eq|CsUE$aka4-IOB3d>*I6f%cDo2Ai*!e&;y3teb09behJw2F;Wqw7&w1>+NV)`r_3t{Tngr2D6W3Mu+o4g)!O-JB*XLYr2La-QgqoY*WUZ~!{a)rZZI&UBW9YFLog=t()gbYTl;M4{ zvuzD4v;U&6Wf#e8tv^1q?!80($HTxY#;-0`okw^;O{7=poSdc3CK&tR?`li*q8s|r zLP`G|OP;#_t3xnue@8>Y-)jg|8{^P-XW;+1$`JlP&rmG=)eZVHq!9Xf$i##jy_K}W zgH4VAq*8{Wq2VZ&Y?t85Ygry2=+4m^s6FIRPn70SeW_ihjl6^-bc3zrl117^0HAzR zM!Kmtjt*0I!B*E4*Fm#is!|BdqfbfD58}vNOiOf(kMLyZ_!1YVwwA}KBfFtnBB?U+ zs=xj(P^bnVk|t@UJM95Z!1iwS!T<(+Xy*e|pz%eH@n7*Filv0!R*9{nIn&Z?tW=*T zd`~2G{Q12i=d?hCYW;Bghc%qJ`iwj*mPAYoqn}iI1-SanB2oH0YqXEqjNR8HalCsb zG#?8Vq#U{Oytor1VGX zlK5HgDuM<&#r-Xc%qMYqU5h;iO$lZK7{uWsL5}@fEL>!*vpiQb)8u))@C2Sv#hXim z;%J~i#AG`o5^}T}drZg?$Q7jH*8phMK|nG!UrF{r1H?Jj>t?xrk=bR1eNPSJ!;L-2 z)|c}34q#~6jet~MBZFYZC^k7f$fX@UnXFWnY1o<);T(3N9eeIUbU_%3hpH%1W-rrT zQZP5BJxX%oo_^0hGkeWRe2Hw!d7|C)r3IxJv2$@up?mE)X!*FgPg0$D@$AVBS%~%!mV`Coy6P~%lUbkJLy8VK#*Vn@>q0F~q_wTn;u}!|)j#k;n z4Qszn-v%JRULF&@e`?h{++7i8_!wRb{Dmy^EkK7QPPaE!8K7R}gS)mM!tSN7w?SnI z#;^OCJO(25BiS0W(aQYYs!LRdk9D(-hN~e7L3LFsb3Q3GGWzjG7{Q@yaq+4;~ALTi_BQ}_@+Kd zt7ojH@0FR;mTNQdaDK#z#0aX})(Y%3DNUC;rA9_M^f{Cs)Z_ zTD%rjQ@?(hQPMk`R+*4o^R~h2-2Ba}s_u7t&CaXA zNYCl`ne9O;F8hnK1CiB>P?V_2PVj#XH2;-vUSETGUZ6~%$3n;g^u_Cn)aG3Hd6=FM zRQ5=lGw~d?zp&86!-3@vi;oDVJrM%Pq({hbMmit?5y!>VmyrR0y;3wFw`YoeL@zn; zD?cV?xD*ebsj~MvD~uIt0Y1Ylh>4$?owKr$lLN-Rh<&eA1|doe$o5MP?Uu=S-vanf zO1u9Em2L(;Em#8=i4s(7VcbgDk4@ z#$k7KoKrTv^gTV>uw-%dc%eOLdYZ#Zn}8Ok(lTjjKx!bm} zlVz+HiFFZ(y51@3IQ#XeS2Ka@Ob=%AeM+!cdp;1fIe%_#&E#x&>6vzV)b5%OqVQog zs}KI(;Pd!V*J@$cCCK+s`$T_7`1SQWzZImH6SBMNBW2sb#9`hG$NydiHof;f0|1ay z>u&ZHYglTK68Q{S1|OBs6rU7}5?GFfgyf508Y0NbJh9!yZux*8`WS+!+I^)^Qg=~{`{Y&sk ziTc{XU)d7PMxhZ&6{4I-N9EI+j*9nJWwBk}0s#Ivk6*vZ2)2%4CMNwy3I9F$T}dHqi-{0x}P z8=pc-0mC;%=q`B#ln>L>7$tlP2N zE7<*t1oG`Jcwu+{85&odLM+Jkqqr8J8&`L%T_N;&?W!YT)7YFg0qgO?Weormi7$zm zK+8WZx1gjsEfEv0{-emTFJ#Y3KTO&++5T1hG_(=DnVeXD?-;i+!2 zk4u7YMGK5%`1GaQJfq&>qN`Y!!#i*-)5fu(N!BsX zim8=r^cN@Sep6EdffCI73zBIKscP&WPlqYA-+sS)F01?eGhRnj^zCQHV$l@rU!^?# z-K*|z5aS1k&RkIN)Ab|vbJ^jX-^tGZs;EF7^n(i%{!l>g2y_`hE(CThz6Q4m{lMo+ z?f0YvaO91Jq9^d^j?TP`s9jKnOZZ;I?}r>h1NVxGz?w{m)PyBQj2{;3rjHsUfT-%) zwWk&#)1&G++>w_w_@xro2aKS4_9?Lmiwa(QSgLPss80{$`*f}S1_mE!M^$dL&8Y0T z{O5qP#@j2$galz(cxx*xUGqkTmUTLD;g2r)`=W+&j32f9o$iJzWp< z`@CCwtPj2uh3q`LXfxh5IS1!|Y5G^CexRhV)#d#a;<%J^UkZRp1m5r4$FD?Bg`r-d z@WKHESYve>A4vy(XwMSGerp93uzVVH3R}U3Ie|wb+iQT40uZAS4u49b4Q(d~MZ_7@ ziKR}OB!lx4>&FM`(P!<`Yw^jh*w&sST=?sF9z5W!&Q1x#vjLmd+A3y zS7A1V6PqPHCRZBy;O`EEVbJ$)y(bbm+V>eAS;<)_tgp${(i%D*t(z=DU^pA9ZA6=K3h~FuTHvg$wi*PA_pZfA1P>O z{p-og0yhN@C$>kEsFeXi;&|(2i-?mFQ-Dq_Q>C&~`WMh<;!n-(k38L<1}ZwX+S-G7 z;sOkOKRW~-tgYQR9eS6ym^AeGWUiI%_P2Ep&0F_&P|6R#B3t}?UWU%Ie(Q!Jpspio z7FIZ7u*;-jXmXg;C~&~EKI*J52Ci3+z*XOacCA zhjZ?9u+e!%(oP2iO}1D0*l(WCZ{BUilk&59)UE^lcwvtTKw@y0fcb+wb%4+e}cRULAL6@QF7+S@=UxacvL9Vj-z}i%9Sso_Pf|OD6YJ82DoQgtSCMUKK5Vx3b_MBuupjNn>6_ugS=X;4CCq&sh}j`+@ZpV*YrL#mza{N^##VXS zNYW*|ijY0Tid_q&uOa^-QNYLGq-Wrz-e6R7QeKcFJggmL#-4=xYoXMP?Jw9~eohVx z&4Mw$h)(%CA-WLGjJhyfL`W*)5DwfR$*?%qr$MSugP5+ks+fp?l0BFP#jyK`XfIg+ z*AOLy8Jv*?C0IVh2(N~d4+%B@yBqCx%6z^O~EHGb3zGv zkoKW^jX}a>j|zEd6yxccX_fnJTw@!2W{uS|{u$TEZBs< zboWElB$5bv8!jMdT#z>p7LP^>rzM>UvY-y@m*eaU?%pfz^=m(eYs`EzJW4l9Yk;-- za`qc28TktpQW3rx5&!`vgc9r1o?9?-L=poawj3G8^d2~x@njeQco%p;%+T^BG#a@v zt~5iLf{jqUv9dHu<_hM#xAdKnJuDZ!^U@NOda7&eFf#`-DmjWHyA=K3 z{asnqv(oJu-+0eb{wk|k22qv|sy3QI^D-ctEL-D=Z2tD#F_KYAc;OFO z@V#cSS(xbzdYtzV{s@^8_9qFZ<^KAD&eC`^qTas&fjYooC~afr3A#;?mtE1P*Ovjv zbG^rN!9XEoR>*lwM5ya~rsHm2ex~x$&J3}m5_pVfLynu9jvp(Zotutx%b!~gq`=e2 zj9vs9bfx4sjKX;W)M?`4X2IcnvKX2H+=P@4u2G`7QuCu~elV*fF@*=P{fiW+0EqL@ z^ugN{@N>rgpKL1?%Z&oj766V>gfU7e1fa@LG=fm`PE0}kg>ZZ z1s|PEHwF~WBR=HD*Co6`dhhysDp@i!=9Ah{JVoqLNX`2=+tS#>O1&AX2?Tj+IoCpB zDa=qT59+fj%|y}?(!I-Sx zrU=Cz>Z?GIfj)PV_qL+?xi~my+l#ip6gO<+M@OG#_3Fhyw*Ng-gK=1El4Mp8#N_Ql zb88zuY3VCq-$rU^$aXe)aM6s)f)b80Oe{G}O#IUz3MfkimI07t%1uWI#%|@tA@Xk( z6X8@7pTzjlPW_kJeHNy?OZ`Jib9-X~EM-Xf%qA25g9VojIfcEC^$7g-~+($6Rt9MLd&xNx{ItGyfXUpTj_?eHOW|H-rIbfJ5g;L!0r zuqF(7&f*uoUCD6R{DJJM+Zoe_MrL%Ug|Z#gUswGkX(OXS50}cN4NEQFl8@>^I0Twt zInV~N^W*7SI%C2_AJrXD;#Fj36CTQs#$L^Ag41y7GWR)G%FI@*T2=jnb4u73-$@rfMDQl$Nn3Tp3x~^e&;!T`a1pF$r zQlkrIPO`5<&vQDiEYpSN9s6TGvMSgy7RIZ3lT=X}#};IVk{hteLTn`qh;Jr4OIp(% zZ#W#r;BmXI&!Ws+udnfCSn}t}qG{?+8%6`q!V}D{2@dW#Ydr(I0$T(6KMkSp1PYjI zK?KU{onZWVT+kK8b@FlKShUXS?@VFF&4ibIjJPQ@?0C>xfo5FOG+DFA*{olP6yE0n zOp}Sm;bF~O0iGCiFyW@vrPT28sKD&(FaXIQ2&ZmsxViY0MKMElSj$LM1IwYS=2amT z-Kh0Mu3x|U#>J%EimbgKw*+2x(ynR7SSAKtsqKdp2bE9vU)D*+XaSCs-jS+;_uh2Dy965Zz*R zK;zlnU1^H^xR8A+AH{g~yzPNuGy6R6U;@={tTR02*tv|65a0F;eyE0qB$BW~MU&Cx z>39hrFl4wnOpU@&VIo412u+hLq*cC}vaTOH^#SLosR{dO9Y0@>NTUo9uF*clFv! za~@-inl0ML61(&)=~?BR-XQ(&Ket)AU>DH&|a>+H>b>oZB4G|B` zQKW(kWlYWsogktk0*DCHQ3426;Q;VeBh|6RVo69)y^_}7(MSMk6gwIAxLac2847`E zIEg20QX#==r9x>56*4`H{};-`q0YN%FE<$eDH^lM9;qnIpOOds93nmMzgubl{M&`Z zQ$eq!AK}xrjd#umVwtDgz!}FG-LAUMclmoxb|C&4maLuSyS5%W!Q}b_glN1;soDCz zV$J6^vM>9mX8# zy=@3oS_ne;yDl)uu5xw$i(9K~1q*^?$pS|+ty-iwCL9U~0A@xMD+1gC%o$?K ztbu^>cM)_XVWmY_0Ev6*=#XET!>b%H5fafegOeecf#Yh5pVZTxoox?t&YeR*zzR}B zF*v99X^e}eYA0glA8kga8u^``BW*T*zBkfKyf4n^OXzuf9^dp7f>j^jwEghInKSa} z$$14I@`$9l;*JFzsB4?S)w}|YS~FcMlAzOWSdNzDG6q!SHi_ET_8auNRje7E?)1#G zY#5FFT!Djh3z5XCd(kgT!04~4M#B> zo9O^BGB9D*B;jVNMT1GsAd@6~u$RIYM^r4h*`9C)cC1cV8JHrel@Cs-?vxpha)hl> z#0FO}jvK=vdgo#FxYr7qwvD*3<^D5PTnanW`4ge>~*iX)gMrnz`+|;P(cv z*H4en{qyH<&861@4IT9!AN1R5gP$`uzg^s}vTS?jqCI$beB5@)zVmhXxX^P74X{Xi zW{lY>mFriF<A{%VKu+pj&5}FF;L(x8+aMjV81aLzh6c0)A(-=Jq-Zy(OKi47~3P8pc~XE zP}ILy6_^Mi#Tm1k;Qs|nCiEz8%L!os*V79Q6&F%rF<>tF8-T*YOA$3W8%l* zFQshHMAFDZ?(5kMgeW4KYnr4H0m&tX)c_xF2k&2{!3WrKalhAgf78ncIgnz~J90q6I{W=xsn_*QQd9dYw(J9SIvRQcheSOR{ zos&~HW0E+4)|UDB@d_Gw{!Ur_?zhskscfHW+C4NfbVMd3sGABWt^DNz0`(brFV$95 zW~pV7%%lZo7`E(4lwzh>-8NZS7z{vmh7dXaoMcP@Jk3miAV3+RGGI2_u3te!ci$xKNhPToChCTXZJtk6YTJ>L_n6 z`AFi*YcXevFBuZFMNmw#;C;bx?Cce9@!31m4}@yRy{D`$Ee-d8{0<1iET8tZQDlUw6V>`Y|z+ge5dcd-}Bw`V}8uP zbDnwDtiAWzYmv6~+r}c{g<@b`f!1u**8TmPjBBM}I!!5o1gW^cmWo9-VhomBNxk;p zOt#kFw?DiEVwrq|#vFpEXWh~vtYH|LWB>Jm?SKP1BbqW@=@o@rI3Kq@TX#l7s z?(n7=@UR>(I0$Jgp4ttTM(Xfr!4oGTi)r`;?1V!y?dDYziAGTL4jBmqI}>6W^f>0u z(s~F+SZIu*ph`BBZd1IXF#JJF>O@BLI;d=K$q-I%P<=9c$f{P(b8>;}S>VzXMcYNh|h#pe$P67hK7 zOM<&!?z$)+ZzA`O5LXL58kn!+h@B$PRa<1B60A0`Npr+$s^O6M?`0e8KgRihT5xW~_^eK4_94G_*mZ9&(00 zOTp{~~vJLK>{xomwuwO?&~xS{++ZAyvPylG+1FD~jS$AE&S5>%Ba`{WUVR@N_30#6?RfRktjWpMdGcD<{J z51u}d@m2m)Id=r2df;J^59%^T<_jQWh1e+6SF`n~E-pIme|inZwR@HS!}zmCW`;jN;&(>e_y}O0( z>nD6>m|9+rgs!)G`0_u}2nO^o+IoJ5eJb`4-j{~_=!4+#By~mO6^;YKTd_i*u$f}A ze@9?dCqYGs!2x6^1{drkuoxSOc4w}J0#t&G=z|Lo0s)Y+tovm1@LM9FGMGYw)xqv6 zc82j{+p*u*y$z!I^4z{NQf@bIO`0TQ6gXwSZLx({pYuJEh}(e{Z|~m3Pvt>W_p(ge z?gkHylzvC-zVwyUGbqTNYOF%;oH4E6X;|CdH?gC+Y#!oxMf^}(n9C1HZ8s-6=CxbG za7@}9EVj3}IA6NDUY?(8w;bB_UwPxS9dtLTnd`?tTq>V09p5zhN)roA_s|N%P%88m zs@nFn=IT$Op$`LZ6UFjN>K#8SW!X`t!knMKkq#X_D0DIwRgdt9h|=NRKA(iM0WBfq%n8LI zvC#Rp%`~BW>#918$pTwZ_=CPr)=93aU~a!Z-_2x}k426aNZ8mkE&9?hO28)Ryic+ikqq$!rt%7y&@K;bNOG0koV^3^FTX{sAwaD%V- z&tqj{fPRD*2ykWEw$n!y`3o_(xPg{trn)8)D4nXF7f!LON7{!%1k`vkj%0*LJ3v?O zrW`nMHM7@h4a~?m8Qz~u*f-HCY`_Y?5&xM7Jdf2{C(7aLn6;$*#4|^}`0kn~)KJD( z+vT5Q@?LDQ_9Nf=?uD-~)`hK;h<07C!jD;D|CDc-wabTLHq?Xy_lH4>MSRb$DD&vC zW-!9-`RW6y|Nmm=Rx@NC)RY7G3-0ZY_qyq3i@A=zLJ58NLgjykb-dq$bqLvS(e|N| zl{rQB8fOE@Sm&*)jx!on;ZPu_PoMy3o|w+^!eNctLPH(yhT0RyA>j}u3Nzf?Si-H? zMFNwdp>n@5x_=6bQ4mTzMV!Q-k!fc#ExZY6d)oYrYW0J4TFaqTn%0uX5RXQZPe2Pg#+M?{`ZwhA>12O-~_j>$z53fF(o@wQH;Ts@i zl5oe%{JvIL^I6HEYHxkyqqz`q1e#^-E@Fn%e^=fxuHtJjB8T-DAzIJ>-u%rYWf3lG z8*EmV4X&U-!G_^;jql7|y4yl%QCt8B;&vlya)ttN*kGP?x6kb9S5Epb5Vk;bx;Tz7;sewxu z5jn{sT>@)c!Z!qK@X1wVpG`WUpTblVD_}a#attp;W`0+EFoljne2juci2$7q&l;2| zoWV^4A2rs*Q{dwq{ksqv$ic-yjXZ;2!s0S)&M0FkI5`;^?CcYq9#M#(AC0p@U!g@ZgaH3mkG5T^2Y2owlN zmbtyZ8xa8Gy$M71C<~~^l{iDzIF43PE4t9f91^2!CF-rzgKBIHy1J{wu+fS7B7wM4o~HC?x@^Km&>!Ph2fx@(`O zFGl80l+}Oe^{qIusiLXEyReZLxJ6_|vr@*IG|GZ9N!9#6TKvI6i?> zRM1A=#sx64qlkQSqWULj1eXt;cIvQT+tydq&VQ>9WQzF8|CS`X#2CUkt{@}0fH;Xd z^-As0a}#b?nf_|%3PkQt&pkwOf{X0l(W-{k6pi@B+21sy`K-RrM~Y87M=a5t9>~x) zjk@njWU4v&nc1?rzn0@Gay1@+^A{^wCVc#eJdL-KF<|6p9Cp047~K#LB5NKK?^Llya653q4f8dn z9>6r8sIJGR`84enKQDc$In4e^_V=Vjzq`YX@2H;$uZ)ncgo&0WPM33dI=haa)kegT z{nDa!vKlsn{khHS^E74LJO4bsK62=x&Ad+~b!W$4z4BLnxiF&Trc1upULd2GUE|`Q z-9~W5rHKXO12xa?b_ZQY{;B_c_44vZ&X)JDvE38hbmq;%oE94-&$aDS(h-(-qDyXz z7+k8~9}Kdc0RXXVVNT%z!(;*M1>aU6`_4d$gqMzUU|EK?x)Bu%yuNv@IAlRUt_TfF zFF!6h!`F#~RtdbF&v2?Zdw8HNQp%doP=Lnvuj_^!s%u5OvADz5w0g zq@=Ntnb?e5laEnhVZT3Jn$if4XSS`m81fx6pIJJm_n}W2DSbWd5<5l)X=JL-dyy!{ zxpmu#3U%0cX{Z%*yn^AE{6aViV0y08S?_2~@Q=!KB)5>VnZGv|AE&1ut!}F>8dLY~ zT&@&Mo(ZREOZJo|`uD}G7D6BYbKa+SQJ;QpkGxD@MkF8J8hZWwIRCyuXn=YGE2crh ztPFs6>%|v_gVTA8^7JPR6jdRRi9j?g3RReFXCUZ@=q<~J7eh|qm*X)IKfkK~EIa~|4M&H*+z{FES|rE9NF zRTEz%C78jEjlE-Xo+cx^=%j!1^|G({K9Y8LTm!#p$jf)@&O5~#-4qL$;81U!eP+Z z01-ey1{#Yzv|9`xFYt=YRKVDgM-LEW1Sr2S z?Lo>${??XKfx_N3#TblemvNeH`rC-Efea2#PeBUXm$t=AMC%9w*cy-z?3hI+V-AiP zbw^h0Qb)3mlNED0W>SdjMWRyx0}B$Htk93P?2jS>UGs5-JFs}*fZ%@=Ijd9+T?Rh; zKg7D+Ma5$!_QMDL`>4h$lvK)6CN9ucm2f4g-*sd(M{(hc30M{p24tLUBxL*_Z2ae6 z{yEcF{owvQmVYLRdSNodqsE?S`U|uGEJaqQ0j`{BgG;0!QD9*-U>F+uhkWlqVKN3p zR6+l9Oo1*Qthxh~Dn?*63={p%Cb=UD*o(zojExBrDWGAH2Dt%G`ERHgON^x>Br?s2 zmAZL!FduJ`JsBv6114m)Nn#wTI}FLQ4Ob>Pm_m&vjR`bL1}DaZ0UJeL@~1K|(=20_GU}Jc za)$;x<*9tTBJhxaoReLZLx-D9Uxr8~do{HQ7G{`Zw$X83@2kI-#>aa-c(9+#U1ylw z(|}C875^zei;C&n{%$4=O-OzwG*4~vAq`52jJ951A*VV}86qb=V6Z6Bs0)QXR0g-8 zRNjq7J3&SZWG*xo)I`|mywbo4NjtgZqv<_g95q1L@KyjMQV(nWV22k+eHE^MMZ9a8 z|J_nT{29seMf!k~lH*EkK_ga}J3B{UGVeirVkt<@kY1lz$8EgTf;Udq`lWXGKC$Xo zn&R=ok}rP@O8Qbs&rCtyg!-%;lfjwHSc)~@*#myFeeFqp6%uFLPs#dso%gO3vxk5k zt%sy;N$KkuF*ZaU#oOh_X@`s3Z)P9Q?|xuUfsYtb4*~92PL9rtr!+N=jElObkMWh= zwG6cf9}2e{{PF=QbrFKUe&%7TnPTQt(9wYKfWiP3Bc2%8#C?E;U0{Yf3nUcX4Qadd z8QL8!I!rP|=ZYB%3^kIDp=~B+Kyi#a0~1UKG#`@PxZ8xVzJ~nf4j0Qhk9|m)-Pw4h zr}5rJQ4Rc)Mi)cEVkqz3^;h?8Etxg94O+o0rHl76`^(Ovev?BTd9D!x8xuVYOEtlC z1;dgSj0p|Le*IkL7#1}VJE!E9BgtTdHV?cR`cmFsGxQT(7qw;^U4FkF8#Anh5W*Zc zCY_;Lkhe-xZi%iYz-Hfz7rdwU=|Yd-iRG*4w5Lfdr$$yP1}-#l(&O zJ<7jkyBL&20S5(TdN}8evz!SO1qQ%3(W)yJqSbgOz|kh4CCjF$fba-XJD3gAbkG!y zbYSP?A1Dw4;5h!P9sn1>&OmVWK-&LbkR&vV7(Em}5CAh8gIg~1P`UwOYD`XhBTc>_ zZl|djV1di-x}V9%tqaaUf0a(v%7ZJi^b=6~B86Ed;eOtAiRZafEsCo|SLcvr{s-y) zG4k5y-Bg&5ob;-ge&75?+^e=#z2`{iqxMhEk$b(^F26(WG;OAw=VvF6j^*oiyxZ3| z6YY8zMII3CCOr2in<6qDIYrjM11eksXC>#POXgvb5ZjOQnMIU&2nq|9X$Eq_JE|d3p)y0XNAaYU zOa3^B;r>Pp7B6KUPGB#!_q!&cM!kNQl_Tf^S+`5knG7yF=M#iM0{O^z=|1h^INRTa zYkJ!=idG^k33%2ix2`o&w!PXp_*;k>JNo$dyZd+D+gC4?<7)2t_uT6F(oJ!5di|8L zY2$Wc#yS|pw)5$zyNx#Scv<%AIr+X%l_=ol?vB_#GHsr$-D0CVj{~-Q|DSW0Z*WDS zn!fbL?rVPE^Kr^w*YXikP#UXqjeRK095gOTM29yUX0nR_&(z;5x*7#34@89ppvfAc z;YR>W3VXqU50H?9C~G*+f-s4Z?Vpvo$O!*}qZY#{2pS-4VRL}OxucHZXyi^wC5a6c zF=#7r97^KaN@lFim|{;DWW97ITp-+T^U>Wj(m_+U!xH&!rKA$=9OWjsRVsp-$c*ev zY^2h?!a;d81#wUW-YErWl$FAK2;-@eF7n%~K)Hgf!U7#8v~YAxd;184a0Wx-smo*( z99EQ~$#QE4CQ%TX1Ufq{m>iop4xr1I8J+Z7VR8;-pcKdtqbTR3?=$Bm(Bhz+)FQEGSIK0zd#3 zAQ%9n`;G=-+_%Ch2R%%1+!zI)3X#Zrje(JgKbDf+z;~+F2>+kIJJ@##+hP7+x-4WI zqAR{E>KF0KXe{Yo$ zHb|g`{T4q$;96GCOnKa3!ZhLQ_v0~!re#jXv$F%QWamm(LDn=i+g6VLo%^DBYUZ&S ze>-uDm?|6Z(07Yn1kG=pWI&@~{{nkuLSco$Cz(Nm*?$D|$ialxT-jd9# z+12kn`oO|pw;CQ}00p;n>9l)7c1cSmU5r|s4q~jdYaiXSJmQRaG3KV$UPtP-NW$tj(zWWD zYu$&n_d_ReZhx)5f>XxtXFd)E-~EI>D$r&{VVR<%@hIj}PYOd_=wqq9OTfISJa&9P7wCg zFB_)y`~%DUe;@yy*8zdsMx_WeDKtp3Csk;yRjL>p7;587?I6Q z=OhNFxxRgx@mdS$K2Eo#`r>yILU8W#yC10qdPORy!u-CuPCoF6KiA&4&1%uY@$}&r zZE-SdPM1x){R3a^>xIuuCRoi~=i)|QDgX9OYIy{a{&d-SBGVzg*zZ24D*yaDLat6Sag{i`V%ZCpYFer!v$PfiJzqJP-y-A%+ zfHULT3jzcHoDd4=tDd69Lg*r~n7edb(g*~JuA-`@9_agH#u7!yWMq?Q{S17Fdx5xQ zGXz;_$`le$T$!GFL2U#U%X-u?m?9Ks-}SgzIq_NZ@FB8kHz`eAD8mMCpr0*ft*t8A zA$RwD;wgSBhbOqGt}bQLD&Q8JEo*RC#bW%-oa@ z`cVz#+x3Lo13P%8El0ho^2cYfMe?I0eDC|{_ykkLjglEDL$3bRFVeu3syMXwO5)7ptt6~8s zNr;Y&v$F)rh7#Z#xnVkk1rLAxId-0eg&G4S&Lcx{{KSxt-;A+xfS*m+WX48fBm$Gh z{9C! znEh!gCMU;|#bR!ol*{c#73gX*f)@mpp@{hh8=kkN+OMT#^k z!$=^BnXW{NE}AAQ%IpxU0OT|*-q#@P6*_<2v}`JoH*T89fQn{! z)z$*I8unEr{=F74le zp{EF)M@88oLSVM@%C(|;siiKdE|$!*WZREM-BFOIe3Cx^)@O>5bipwrT)A9yQNRNr3Bb{0v>tw3;0(y zFc2^o`6&DZROc{5gpD9VKZM_HQa2t;b7Ua1bp2sePOt)mGP75rcJ7T+mvR&nT?9ZM z2x5=Y7pKo*Vp48o^#%V|J_NvZc&xx$?EsGBqsb<_0R&66^2Fdiqd8~gK~zuSdCSoUrW$>H2D`R0WdN z6^lynipQ;WRGU-Icd>TV<*F>&0wM*v2}9ZQ9_XQCZMoQ}CecLhfW zpX*ntrS^}m4@UUoSe2R6%C(-4zi=BanT*-3&6NfmSrMJPCL``@m2pxvkO9{S52r>V zancug_*!l~4RL>5#+-1syzf>Q&a@srZsC+)Wv{v@?EMP0=$U)4`|7*D?>6;&bG%dK z0+qAEP^G;h3wA6NDXYT~VUov53O3Y$OPd27CJOL^?u?F(m2jhO7NEH7l63cHM`5DF zpVGEeg_DS3N#wP=&RA@OmzJbiq*3pPgdxxT0jg1<9Y>WsB6JEQ?sXp;D;dHj5HW@$ zVJgKvt+MnG)}dFIFQbz~?O9uVA{LMG;{B@APX(7Ud>B-#Sgu~(ZfB=3TT3{cHBF#X z3^mE4>T6bKWpiH19@)aNbyrItR&|nIqg@YL!#PFxc~{DwYmZa=SYPeny*({d2HL<7 z2?pTG#z$JVbI7bsxe+ZgNd+h@@}^KU@E}MoF6C4}dES3P%%n~Z`b1L$$Af9sGWA6` zJ2>Zv+Ds3a#>FM5O^?x#Ztb=TM}0g(PzRbEAuQF#jLS$#P?M>yN}a`3NNy}V2KDdW zhz#uwh!Jr&7_H{UX=fLIb(OlSkp&S`J2==yJY_-8Q3%{vV;*28^9yh*774Z*_vuw) z&kH+dBcqeAVJ2f9D?AM!UUSn1enP7mgJjYo{1Qv3?t#60&P2b>?SPZFQZseUehT?g zCTOVhK(2EGa)nVQrvB*p?5!deGsK>Fc5Wd?oP&Z&#eftES?xwA4p<5>ly~~7dd@Kx zRlq*^12N}7{>L0o4=i_IAZkinDloNQkA?t)7%NlD>@^|X*9ItFha-J2(~2jtToqU3 zT}9nqb?mNPrzagkRiFo4kEH${VVNTU2rMmLjzp?$kifm=ln)`)fOTUIUk$2EK#H9XE3MWUr@DtcWUjKH=WP0MYiN z!?Er9bb4S2-#d5Q28UeZWQ1yU?#2%ydvWoOlQLGkek*0Ieud`8M?LAG&QThsJA?kV zV|l8A;^slzDPnF(BYpo=ckSGf>JZpr@Xcg`f8v|*%r6#1NU9-YW6c~iF%&|k=h4gA z_!G8k+rtt{?8LxD@`PXvc=&iIEG!-j21qURAroC@$F{qAzG}X)C#X8pMc7uWaQ;BG zvZmh{Nc`%FoVq_|opnRLPk&SIAQO+$bnK^HOJS9S?a826myvQSA5U~+&WgTRG+`~( zf}Q;gc*hIFQ%vK6o;~3aL&Gu=&Sk2Y>I*{(I3^;pzUJl4*`k^bde=j@wHg+J za4i%mj8PSr>u~}(cGf1whO?H0)UCdT3r*PKthhP&QZ-_;@%u|n+Nm5Z>wMi7oiz0VqbE$oA46m*jX+?Xm5l?Putks0IWZoG zWr)h64FIOZq*bK9w7cR_g)~;9+l5Z%wU8~87)!?T$pogj#=*x7I=0{j`-+;_29eAt z!Y+N2DY1QTJBX`GapAA# z+?Ht3EtIqF4kz&z|4A-3tXtSDl*Tc;xjbvWMYG5+BelIoZCBs9?p}j*IuUhYA1WCp zDyioZPWi6!?EY~BDMO-C0PQ&=D;6d$LYI=yn7HV-u64qQFzUuziE>NE5KOI?Aj_30 ziNFSvk@{5%bB>RePWSt-oF{X|u!0BL6AV2un2wkvdd0c-9f$029k&=0206-H2K!{F zF$5xHB*{XMHt#}tis;|6s1UB7o(00}8l_&C41r9&y~Sqn#6NW7W40@|`}lIGqMD@~ z32>FR_48^J%MI5Jii8%jH}%I+7?ud?t7R@pas0z7{Mj`z|Niy1ob_Nzth7wHq;ZH{ zvugX{qx+PWj0+z@r?z$*d{JI0^td$O-*dw0!p>jM=4b-PA~pxo$PkyvK0G*b8aJk8 zq8fkzDTN5!>$RrumqGR$3O?i+9E2zeX?ZH6lN6{pz+@9i4mk{i&+A>chchLYtn-4@c~S~5CfvNE zqaG7;z*_kG*q(Iq=8Ne3P&A402oaxjBS%A8s1#w2PK=WNW-&=f|I5m|-D%b4;kVkd zUp8I(UdeBUe_s6G<)=U1UAOtmh$&V6n?9JwKO{RWLOGZ?@0?c!*j?HaS`{jy{5YTR zcoRE2Du-E+XbM3G)`6mGeXqbdlq^JWd#QWR}^7ne^&dHFfccAjWUqhd4_Y5j?G-8)TB8OPNq+36MA z{10WC<**1Tx}H1N@-?6(3hsko?(Z=f$y%{EDb}$V(8L2KWuFDfj_@P()uwc6zf?Qq zKDBY)|JeJu#Q%8?X}bjgVCJggI`ux2B6*>Rn%?RG$R!OV5hW=YMO!u=E2EreWo8+$QVnEq9NJebWyerXZM=8*~J`! zt9lk^IbMVeuHOaj2F|`7qS|oS89r|rO1FN5Q?7heUm5y$KNf%a#_wv1j=)=A;$r{D z_fwljGLuzwsgT@QXa6_)IP)PkA%tZLZmcY#)4~;fuD`x)U&eE%dXv(VD|V@X%4Lx5 z+7qjthU(M}FQ#!}NuY;A=@lfej6SXWfs`GVl05WEm$Tnm+2?ZY@%SV($ei~b8uUwl zs}7J-&O1S7HUWbJ(w3>ma&2%8IoqwQm_EAC zt5|KIUa?`}A);Y~V*u!!%Ja~Xd`auXIgF;IoB- zChNkr?P8@-awXcto~E`!$dcdxb17OKa?YP_X2l5kg>M!XW;_w zuTTf2sMn!kfV{{gb@fZ!yEhT=c+V3G5ta-S*dXq16V&^uDojyeb|Ml^R9B5Oel&6L zi_)YsBMA1kWPA_m>)N*%{mZV+s}VkMK5NQ1EtMv-3&-gThz0bX71Y z41|1V5GnuBt~FFVjE4bk2UwsRQ)tZMdN?jN-VGt1O|c(TPO&|+|KMafFRzoed`W|* zb2Z*h`db3Md5(F+7YNZeoaPvsk=;rm8SQQDccZZ8wXo%nB;=N_HO#H8s&rqYxtf(s z4AFG=^Di&=w_~BQG7?9J(t1F|Czw=-i86Tv2(Fa)!7d@W#x8!QdX)|yR_5_4we-fH z(rKuJ$TdvEyW^!QjH43Le8&xmv})BRrj*8agMWQ<51W2FVT}Ou z%SJ^YC}HTOBRLWf;LBw$R*neHs?T52NQg32STwp!#tIv%SF<+?czXh|?Oyl;Ul3lr z|GK%yI|p-^yMwp2q%p*jh-63t_&Jv#+$BVvY)_RlU-JkA3Yo`P>)&@frv9iJro=*wibbJ*8F8+$D z&`Q6runEQdgLc~;8fQ|_OF>zrE^*b`P?b3y8D1-|EiY={iNPwUpXB0r#4Mjg-Fp^b zEIr5;+C9Kp813XG4*!fL2o0?kE`6n!TmsSVUV!>Sw{c(^z0>v>x1nBjI>JlFsJpIk z?`rizX9GJ&l0e zg@E-oc3bIZZyT&%gNRZ;ZexxJ12wa05Yf;CR*)MX_?Vn?kv5;-I5gPD*=4+dM$T#p zbo5~%tg2)lX>cM$unniV?FhWeD)Ay-T6izQ)L-?G%n{~tc;q4pFlaGCaa{1P;({ix znUTg$C_-1t=u{ch9DQ?QdK0zIU_+CfQsk&4-|gKKjNCHgF(S@b&~HND3BLc z%c7bv51Me$Lrj{ra~T;$+R6kgMq!QOzA<8=1F&zMT#`jPilcmGSE}|Lvk10`w8si6 z8M1|<75K2Q7u*-UJ{d8r=pJu?gGQM(_EG8S^k9T*=zT_!wt%8n9b?L8l>FFnf(fU@ zvcKC^hZV^HMv^2pT$9l-$r|Z%25^H`-7S|*HRL6==@(43m@lLJ zK)1ln(Vohb`~9IGqo^{#aamKO1ENIkL;nUfhue(dx?7Q_=A_LaAz^=b$ZR2^ThmOa zY2nS%Xn+1brB&MX+@kvP$$>x9%myj#DK_qusA}~B-^6Q5(ND1S(6`$B5I0`fxDZh| z5v{xKZR(crLnf6bT#q}WSJv1yl5UX&CQ#lSk|hc&3Oaplxv6TF9mz}<@2P5TpPQR= z*mYG`1(As!*162O@KcEw4HcwRC;c0)K7*^y5lVik?oU@!_$pzXgfs-l^l@-XT@(P6 z8X5+Kd~DK{;#@Kbg(`(2GCnvXLXQlNAuympz zz}N;It(kH{x7M)0JFgwYP&YR|EDihbRLY|$QDg>{&YZCmdlg@69xz(9@pE!pZ_uc) z4Cj^D+wgN>Et@5Cfl{=n)O3y%46?c{1Pvw#v|~>MH#+=Vs%0Av%PtLixZRhcR@J*q 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

=*qNfk37tUo|$sS7R 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%0DbD=Q&&5iq!keRN^+{&aO7g?zDnI} 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 O#j7ZD@mP4-eNm$t?fgz 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


@)57~uOr=FRAXMCwOY!PyU4XNxrLgs) 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≫vO4n|=aDVKwW4}lU5Ss)4qOjHIO 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
  • 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
    @Fc8!B!yT=kB)it>zYuqh7{ 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%0Dq$=R9TxAs`uIl+MB$&Xy5?X&v5 zThYpY-hAbrgqyYdid}Ob{LX%NOGllyp!Cw9 z6eLdtGWI76HAL=)J244o#601-{F^TE)Exy1e-kroV_6E9b3wE3t@mHb=LP|RZK|=* zebO^O@ZRiZ5iee}N`$i2vd|gFs53Whb5G(9`~VZ5qgz8BX4EL=jOH@Tq>gi%lGHN^ zW-2>ft`V$9I~T9yyVN%!lrda&{S$+L&CK6nb$BU8{{o}sV#!w`rzGzyZ|j>$$1Yy@#?9B% zBm!MYq~S@+LKapr8CPx(p!h^*z@Kp%MJ^bJ1q7Hd(>uU+?VkLIF6lA==wGU2gaYj?Wz^7)Cl*4NPrR#5VAOXqw9>j!5 zo_A~~PgAHraHWz74<41Qa}~YN;-d`x7-z|#yV{H7m@Q@wrDRMe#gaJwt&^*eN!Rb; zYuN5BPEDB8c6@al_)g(u`~i8po2>gmy}6Mx5S_5qav1W*Ho!GIcp_$Tpon@-3>$jG z)1lMk*}f59xKRGWitGFMBadzoHc=8#5F%JU_>nl7d?KMzy8+MCA0y3JXTRlu-04ax zhyKrx9}`TZonmsCK%==dy0qlEle0yBz@i5%Pi*8A5-DKBl8r^vWPZdvph9`D1{_jG ztjqdK$lq+WS_TJF%7xr9(3l5h*wnb&pfXhO08?574U2(bL3xQ-Ur)m+0=%z~wVD=< zfl@=Ky`W&v;363-5&?vQbU}&Aqc{k)A2@pN?E8@3kMiFN%}|Z>q6e`>IlEXg`j`$Cr^v>~lxtnaeTh>lK9%eeqqC*=8fZTj&{>hmrM<}eE2K3fCyp8#IKFP6@nn7KtMj) z9~Js>{m!$ZQX)<3iSM~`-~m9$LIAmSBA|zWfu$QTGwj|cir1I#F_XDR4}@W?t${=U zAsrSx?Kj=PG$XsnL|$!PDj=E;oYy#=8jiM9W5K5;=YJ3`2ZI_abe=bAL}{vE z5|C8hBL!20_#%1Su`(jbr6iJX#(PEL!J=s{JR-&MRH8biSvk!^CBck7bhEurYvuC) z6$f)GJeus8jchE=Z9XrWeCEopEKOY-=V)m2r83ls(~O2q?IO@b+Ju3o+|I?$7xH+l zeX;kevu`^5!0+O~ahgAr?frP4*rj4GYs6NEd(`_VGh-=x?J}nu1IY7_-L8r;N}ErdN~3 zW5fb`&sm@hEWsqXp)QC_Wj>m_(L84qUK|bB6}pI;fBvAXf_^yv%&)LCQgFASTc${} zT|W9HR^ZC|t=1z~%2M_R0S|3vuT`}rpBOxS|M*Y3{U4u{(^Oyh#CtVi^OZ(28y}-D zo)#Z`&T~CmZ@ZRP!I~ba(|xx~B|#gXUHU>ofZc^5eT7;ip3>6mP;efFY>Frxtol}k zAQMQ^6DyaQj1jgqtI zQXz@)i69n4PsSHYeedNBS_-CAhZND{hE`d$T8Pj6ZG6oAw`NDX`f|WY#4~^NwNFEu#)bj!Psode zhrZWS{$@)-JY)g)1AZQ~A0?^&!{i;0Sf3$2Il#vIL--MrnXc`lfJiWmCKe!#M}5K$ zx3|0$0iF;7?HOT=kj6mh^${#qkEOh5fN6+epLlc7Pt$Uwc)5#5W!^lxLc!e=N=_&? zP6093oce^|5XBaj^vGy~sFO!L;_X*gaP#TSdf-eTU^Mv$h{^yTSVP*6A{HGZpQ6%x zUi@MQh9rBGMhfyW@aDED?M$j@d^Y|^Lz=N5t3T?u9zY4RC&yq*!&A+cVS}&wQz8{L zC&5|V3NI;t`Z|5PjO~53v6<`Sf1BKm7zFI9dcsku|;ZXt0ugZY}_EDdj?^i z0@@x)4~X%&zK4)YE^~*UY4G>kF@~W+l%nCNU;zYkrDh)i+ObO!J2UnY!apq=!md&P z(2)EBcPLiOoFHOdM6eSU?FR}MhY`TooIA&oruZyTwC+Rv)Jwlxv(764-JtY(0?Sba~J>U7-jnk4Z@LmzVlE6!bOx(gKJPtFM1Mn zDM)#N!E@8z)49DWwo4ewK9M)$LGK&BRy4p6 zC*D{m{#N9XBt#QLT zmK@Ky8ws+j!w9JPd7lD%b09V2Zuv4P}W$98On&XWZ4ddl6v@LwMf9?e4e0;~Zkv9IC$?ne|@g0x(71`iCZujJg zrOS@6VO;709!m05BNmBs@I;=%v=ltz-5s z2bP31QDacrlyZu1(-Co#?9OxQugX>L3&!xyn&GAL0aD$mf6Jf%oGgm~yx@Dl@N9cR z4!DsVG4fhUv=7tpLZ#nOqyBUfzUZn3w$`#G>>^nZ$*G^Uv&y11JKvD1c8Jnm@ zm7PTu4Q-JP%;tm?*MCWrpnQ#-QAzy!I*}$qD@_D$Yrz!RPI;vDEq0+Gu-I_o*+Own zq^=j6u88O4cx~#HO{Lex#ebr3bnoKUR3oIl&+Yn-rf`Q?K`?p#=M?(xGLq8c*tT@v z7oB3pUGL}1Pj_~-Ke#->;~?(LB%|J<)|5=+?8AN2 zW*yUXLJR?r=c8BPxv_V zYl-e2a5wp<`?}@DkLtz^tab;@!VSy?M&H2y!g{&otm=f*`-o(JWA2JZIV=`o0Up`e z9<lr2;-Xxtb|Y9lmtZImrEcc*z2$ zhX=_%y(`1UVi*Zc%L>f*FAY&X($W#~B^5Au-V>xI4Pm}}5MY}Skk9Fy{<4L1rnr(Z z3J>vipp1>lv_bnHjT}99FN*mTp64q&Knt1zbx3>Rnbg7bB?YGLwk7sTya1jD>m>lT zpC|xfiMRu82ST;b6K_exf~*$oqi9k=q#6abijyn9j7Vb23?1Eb zp0k#Imk;bw;(yFTpZ9fph3nV9?=wIAmM6@+7b@*x3FM1mlMF)r4DSbTXM+@2&tRFn zvO<>57o)PY!D^T3PLX(AglZ&2ETB6^p|Z6S8K?HZcy<&N1D4)}6DXMx5L(+Tup9YM zkV61V=o=c^aaK~pyH^9-Tg-v5)*uyHPE0mgoFysi<;`TtN0d1vju5ahvM75c`d`9; z_pk&d(5fseue4wRwV3WE+ykItaOkCRKU6Oq%8xS!$!uZhy3x;K0D}T&4ASP_{P#!J z&9`H;<^0G)lG-K92VzL1PMY$Cr#D(If+z?F^lXqZqF!X_diiMwY=PF8NpCUL69d1r}myiN+R;pRti1&xP}0#ZmuWTaz0bdwQHU(R64lF zasknX!lQ^Pun8vtM;C3f52sm&rocbn<5bb4I~LQO(M=x6FZY+jAY}T$13ZbnvU%b* zKY@{^&2BUZ+^&prF1jrZN^O!xEggKGKcbdpQ!Z}I)U?b;Tc`I!yQufDK?3cZ@%>_@FIQw+1+dVgOW|FBX~xVx}+ zJu9JcgyM;6xBa0tZ0|C)lwk1{bO*WZX!+GBsA%Omw`AC%8sS!-){#2b`PaSm*;-va zLdkz=S!6ao9|QvVjmiWiq8MlULPp<0YK%m+MEiSLL3rqVBp3Kz3t-Jp6JS0s#6JLW zYk{nKxd~dzff*hfQPZRpIAqd~Yc#sJNwaiU(oa!{0`tu30flN0Ig^3bq$)rtwSNF@ z0DbYVNDMLrLZPjgVLgCTCRRkk4aMkAf zuyH7sgbA~VlS&`$e=V<+Ry(0pCqIA#`5*?B%ovo@-_PIwy<92L`CU|Z zL-tj_nZtq>2reJ80t{Apw7&ev9fKUv+HRsCF$G7GveL6a zNPq+=YxWFFI!Db>V=m-@*OK9v zx_X>!_?Lpom~OJ;voJ&!3NlE;wgo8Ku0%U>D#Pm)(|8~&H|0?-!qI_abse`JKEW*l zmGgfr57{dI)CRsI-{Qag_Q!Z@8r+e*jlYlDd3gH+*xcJ#GS0=7>t_%oIaG3qY;aiH z1DHi-O9<-_;0aLTP`y2g;J1Vrn^X#sxGbDBa>@Lx~8I=#8Fae)5IU5h_rt>l(aPme;N1pr@vc zh!R^M=CuR%d9z1qx3)J@m|DRLv)W6#)^tt^R6I;EDJ|N0%MDMsu{iHk(@5YBVYLNku)zfq4 zt$R#l)Mq3hItTw>W^b>{aVvDQ6tOIC#AMjv(jFE_(PIi+B%NFIdvNT4WE%!Zh$p7? zSR0SgA}C}7mDD$sppVb^sU4I|oHx|e4Qkjb;v&2N#NY#Yg46ON&w|SknGKLO7@CO^ z*^Spou?J1B=ucu!a!)m51mX}v?LWU{-tArmQh~hEn^h6s*rcWJsT2eoa=Om)u$H=X z%b1Ze$%Q@V~DqjX-Bkj#w)RJ z>3B9aw0k{o7~R9nY8kBp=l z$N1nex34yu*pSgdH~-wGNNgWAg9yX2m(UwiYy<)T+JH+D=s_510VZ#Ymy1$mmD7_8 zZH)ov$dH5(5zs*--!t&od$ET15O+T;CpSvoN3OSYL|Vd+{UT%Gb*n+Umg7Tm;5mE% z6_SIU2FzWSw+aOu|LRsApA5sRL!vRo6FDlMr5`h%yJ(_(U`fu4@89z!*+gZo{gS6| zd?DJmY|=K#@~oJza-m+G>(%EMN3%=L60BLTw&uuO4Je|gHO5>=bN`%v(&f)$4dMr) zsZde`{=5AjIt3Mt1GDYuQ*(N6vI1-VnXDX%2u{81)85lFUOxPA>!J@vX-)t8{>8hb z7a24+Z!aBW^>RGcazv=0td~;|FH5b6iwIwhQW{NcNW=39GQcdKPDVzhi-2P=+iQm> z6kH7e;NU&j*_-EVQTajf4r5D+yDmJ8-HD7QglIgDhonVpK+TsCIecx?gd9a*BFjMt zS`G+5#~2AM6GONfVO7Pb&^cHSrEE9p7D=$7zjzv+Gx9PWOaZxeYQB`wi4f4uSe>iD zgw$-a$+W+@V5{!*xTdXO#e2%DV`URZ93?dtXvs$9g=lX3A!n)ea9z87{pnMV($`yW zA}T&Mf8Uq58O%0;_eqW3rgXL1WI%SToV#F`*^&Q8iwm zkYG_f@}S=WG1$@Lu%4PBDX|p60>1WaoV0CZQT%vXa10l*IUv5NJPnNs8F|P+7 z#-fEEjW}ho&m&MOVD3}dknQp1(PL57e?`5eHVmpzJ2$V)XRgxK(R{pTD{XTN3PSH0 zb~*&}H;*3n%&An&TB0`kl$x=F-dxUn;+wcUFjwCUb#!B!%gHNjN7M1b6OFr&q}$(p;%QG&^ZQbI;{Qb-zH`~#IR(FrEmg-OT7gR2 z0TZ7}^E6vcAUpROKv$067F1;t_v5y^Bt)UNk|HR}kH6cOsc4!`vabY!&UNm;O9vN% zMjUf+oBcq%ScU0rBW(qi#Ju2VrL#|B=n0YStOLS{g0?XwcrqN6O}t9xEX*lhye?Xy zv05?dv!VV*Zw zM(U6Y!YpqkCWQOUf6$pMfgtTMUr7>Vp{(xlpHL%04R3Ou&2iF_g zEP2LhDgcZF?NBCNm8pe6bh8KdvKZ=8U&1&)*a28&8OqQ~nAKi9a8Q!aJ@4t<0fctw z-KhzF7$aU(6cgalgahxaZ7U8F6=&T;%9B}AkS6Gj&UiL=`a6?s<2Wa3GG*@GA9@qA zMrB{@qw;kZGlFVTxBHiANRdUC_xcX(Rug~E&dy5{e#oAAwc1e439lzc&k!9wG7taC z>$9)y;GQ~GYt%dc=jwZ(4+oF=XYcr{$y)~;GiW-gP=0_Hm793O6MEOaJ6jg#H4T4c1BGKC8tnso@v8Zsc zGEMJj1OlMjXtN8k4`rD^ApL_@NqdDzB_JFG6!Bu*B{D&9G~hR;O`z*S zF$ZDULyS?#3ThH6S=5IV1}D30Xnc9XN2-R)FYciVO40Lqsy0z#)V65?iZb&&!uapGFpV9(%T6A z)}JcqQT-rG512_@ERbd{ZIhG9^nAEVg&7g(Rw_e?vh|`+Ui6?)unHyIP`@CHZ9qU8 z1pV|0hh?Sd^&HXRS@+0c%Q^{eg>z(=g3AO@aJ)zwC<`{0nC3~c7$Xir$eqif%sVSj z#LKKSXDV8-#_fg$B4$>V!=bpMbr>0T1jtBS+U|i^v!*siPo@&jsigI`em$>&+Q2<3 z%e=@Qx=#E#6hBocI{e{Uc$K?+Q>3+I`k2b2KKIr3_S(I(Cvz4~wR5MwapUrj`hE*G z>aUP}Y$q66*F6>bH2u#aj*Y22`o%?uYnO)EUGIixQv8_&15;&`f+_s91wWGR}#uNq@jDwa#)Mt-i;N=d)><29>r z`psX-RjaL|%=$5b<;);(Lb>y&Rh;mCz;e6#=;G(eRVWFbz$c>ds#4!S_$&$%`q{v6 zVu}ZHdvnbUdDv`LLRMT!1OcF6k0cro;|Aq?&8D_zLxazI0>?9_Ce*N~!-S0zJ%NBH zz!17E$8A1JJegm4()=LI6L6IY<@i%Dz8Q&I!tP~g|3{MG!ua4!*kL295|Ww;5Pp); z+)#}`sIQQv!|KpcxKY{OI%2?s$?2=diJykEWBA{)R4GfRt4t^IBJEcW@jRY>Z(|%vv7v)k!fJU4ETrbfmwoRWf(N4-uDbr}U-f{Q z(_9=PIb8|E|E>0E1DfZU8kf|At$309N8G#ohf~e%EJm|Vx6S4<>WvJcJsUk3VZ|R6 z876~JexAt44V9j@r&i()i^=;~jxM)u6kNXra*>-vbI0e~_}LS2|^X?@9I}%SYGE zZMNS=6qzRI=yy13xnGV3Fw`Pm6;a+8y$#=*->ucq`(se+1>BM@uO1dJMPkpk8%4;flO2F#`we`d75Pz z&;AuhniJ6SsIcJjHumIE|8$&$g@wEGuHwQWpyDMT%FXvOIOY&1Lq^F|Dy!Fwd764B zP!tE4T0SBIAh?fH$g35FDV^sT8dnevgmNJr*Oq3a*;et^cN~gC>pV2)-~#!<-anN^r=DV*iSBvKe?_|p%)EsxJ{BNLxtNkbR>+kKPDS1(rS-zr6Q0>@n}ct zH+9gJtJMTXHx-^+=y;t>Ow5(@Q+}gvpzrvx_1^de?8sG5)tBk_w~h~=i9&-k{Tze} zZ<}4H6+M$P!ddL?k%ZLCFlR9sX6@IJG;2J&&rn?qIkt)d~5i;6LF#^Gse+x&6@Iwg+ z*CVhMYq{O(IpAmQ2 z@&r^%PVl@u&Q1GwpnB3A?)mHQ!KuFc;8E?@AyPvk8120Tr)QnQ$_WQeIk0{{Drp6& zutJ(5fdYK6C_iN$Wf>w1*h@SZs(M6d!kyzx$1F+A2w9&9A<<+GE1XVFRu-q!!t^K# z%wci7aj8`to5%%AEIJp!41#1srwwIB`79qtNSd)F@@~iqNwFAE1j!#iB9+xV!*InJ z&bCzuHQe`n82Dw7GBm>L1Gg}4Sa(g9VIg(D3I0jQTzmHkqSv^og)U{lsCxe-gE`IT z;e)ivzF%3801GLCEt9cGz`YM}&}f-2PkL z_@ape^+m<;gq})Iw)GFqqWkfCif4JQ8Hn(T*SrS8RUlvR83Jc?TS{trK6q=%PM&c%Cv0SHgmr?vVkLK9Mfy zHlR#{3Bve7MB}J9ee3e!T4Fxq<<`B$Fw(#K<(?B%PCY;!Q5V(JeFpbxk;mH)QkScW zn-(7UON@UJpPq=GeGIF5|6IaLGQ@fOYjI?E!wd0IVcx?wAA@Is!hu^fYz~sb>byl= z!-p{`DOB@zk30sdeZ3YMKPEvDEF>#(`wuLf0>6eUgvP7@?}?C3KV*)|366lo>h5&M zqMZjq(A{NlOlfG}>P#vfGl_K%TUobOcZvU~W`HOdzlbl2Qg>^PoZEdE#LCD^#yj29 z4?!bG^yJ8-v9m10gwh#Wh;nI}AwU#TJ%y6a1x}$^&m8WIP7Drm;b~)avTzjuaWnZ> zX@g#|)9aTGH>j>JQV26s^!)aXdE2mXB46We{!=7+&6oKPMM#z&fui~SR_x{{>k@A! z#i-NQcC5OnACzmdZh!IVLsd9D!k!$nja0mO*DOdd`qXc09NR&C{(Q!w_WuqV3-s=s zLhtcSrE>RwI0ZWFe~ZSxqiVZ58e5yNYG|cydX>&rn$zFDAC4`OeT@DACEX=n0upbY zFJ^;~(-rvm*opr3@PawmFg`H2cp1nMl!S+FV8)?)9_}$}$3jV#d9tR!#9NejkI4$# zNQC5g7ZHt_veJ|h12J488DggP@=JnqwK%XIpq!3JJja9JlSd+u3XiO3BA)Z^3 zO?RFs2o6VNZiV3!%PMI1Eig_Z_~mq1)ad;pY3`~HKprzJnv-+$Oo-yW%jngllvR^d z$|A=db+0rWg;)toI|>kFj5%JXd{+$Si#6vGq7RZthH;E%M}OC#`Jm?JG1s17!?lTi zM#H5R9zVlwtK+_@<`t@{C}o^Xb`^jfCXD)vt^0KR*^=hq3qgE~<)g1gJ)@mn3L zzygXGkqVtjX%BLfQAKG%*S9$-OR_KtmwmL;?tE936xd zpCFw5R zrNdByN`%1j*~Jzr7dHrIxN6rQB&^sSI;O;!{HmbLjr0AxpIG~}EJkgtI>NRZFS!_3 z1xgdh@!Gek>dwB~{MjD3AvvAOwi=<< z@VS@%n;z~{G>emM9rpcg*um?PYTKxJPP*WPjrVhEzdguk{ONYoQFFla)50_R_S@-K zQ?g69+PiiLzla*K=A%W3OV zr|^8i3!+M*9?$HV!&d_A3(3R>7Ya%9Ww&M|U1I zvCu%@&E9ZdbdA8kTv%(6X2fv4|pfBlN2zrFo<+kzA{o}&p2QYRGs;FPGq zg0REN;o}f>b(x7H(YR0&+PzM4UVWAeW_!&?Rg`I63yDJYva45M;cS8Z|!;6IEC}MGWJR&M*cLg#5 zXeK4G32^u)BN4jT=sp}&1khU5>xUH$V+k;J5xZ7+og-{)aBhfPwx);hFSp32yd5f} z$^~1kL;lAa^YWL6Rz@Zk9=>$!HIlkf?CeOk`(6^R2_=s!cFm%)kMx`TC@`~bU)&Wp!i6==v9b?vBB?Cx;@{aerM+>=*6{H3CCpx%i>e)Jq{Z*$qiSVemGJ zr2J??91e|-1Qz8vc3)(UXu2&wO$&t++~dNI@hEU{Afl?N88kMB2ovS8%8-?D)-n@K z8qy&)$a}i1XEdh6VD5&kXJ??AB2i@^yh=$w5%`&u>8rBbgpLn=?`H{h#~|4PW3!GC z$`Z9fVz19m-*y{y!xTTGGgZzDB{+wBs0ImaA#a%?-aRC%nv$x|_~)uuk@(&)4MI#B zUZ9y-!_y1SP;y*ur){@2;H_3|57f9$AX{Ty8}O) zsV$A24?7t@54R={ZlCt~H2(X?bh9ya`~Bkf>Kx5+*8~oR2tas9Y)ZCeU~Lf8@Dv)t z$br)2U|-w`?qw^-gB5P*=p!(Up4Z*Ga&mK|XhwV$WA`((Q)_UIA_Z5N1`;QeIV@`b z&?jvgMDT+*$u?Kt-rUbcigXvL$&w?63m$TaD{ShXp0GuGT>EjL(=`?fo{wfd`I#*J z;ph5KC!RR#vO3I)e3pB-j&S&e)^8)J2SqP7O^f30>ImFNsCmIbCMm2g`NLe*SvF<4 z6%-vO*RB8H8I!6=x^Ca&!t9F@iPRfOjT^pxPSg?nRh9dZ{)ZyViT_OxI52^WM%Z%z z;3B4cwR#mGur4i0*NG$W7}~=Z#sS8}b^^Y8&L^}7458-LRG5?ivv4*iE{Oc~94l{( z5?xDHZX?`bsW6Xj4ezXz{&FThEE7u+6q(B$lo*5%>g$t61J(=+wLPR7)OkAI(sSj&5|n&SkMJRFhe@|j~V zA}mtdo{^+(9i_DSSK-XmDM}Xv9|Z_0{6C`3GpLFFd;3WU5FkJZEkMN3J0=i1YUmw8 z??|tT^lAyc_ZFIl-lca?dI#wOqEbWwQ9%(K!o&TW`OmX2c6Q%>XZD)2=UnIdsQL(! zGfD0;?Np-7V?LjFrA84ihmYR+d(+HT(DI< z?(miwNAUAeEG0)gakrAGsfL$~SRIj>r>Ufjs@?*n+n&+QARuV1cmyvmScbRTb8(Lx z4D*?(DiBC5!W=-j0LgqHZ)gROW}>fh06<&+behzt!K3Df0?{!dS0Kf1a!gS^g>h=*Rihhkg0?f2k}#XR{`b3$oN- z>x$q0zRF)wyvp%@^G?_~W(jbOT)mxsW zkNO|$jCQyhZ=Y+5ic-1D+|%oiU49$a+H2K|4K(^9$;?w<_nK5wQdh*)7xvayRCq^p zAe>S2$L7n@r|zSVY!>1^WlOjJw#YP?&pWYeLEozlmzj-u^Qi2D#?OYl-P^`pmVZTp zd>gF9J5xp*>+}8-h5Piuk3&r29JT;2#WzNe&;a&`ZX@W;lwnsnPo-E)_l(|ztn>-K zBPm9&&0Z_Tdv(F>jUkm4jOuSF^Us90>>(= z<9L6)Rv&};=XgF>%)F*-B6pLuroT+xN8uWGsPkmK3vs*UgDSDHoY(uTZH4k}G*TFA`xKm~K38p?3_)J71|M2r^U8J?C z*I1=VZMO_}8N(e3rI0{9x!%GTW{Wabt}V#u?h1X{HH)Sv$(8PDfaV`L9ZS_-FuRrJ zK;-aBt-@F1+q>j{TyJ4?iaX)I4m%Crxw-dS9u|q*@_CR0_znMe&y%6$O=gYIo>z92 zY%K$Yxx{-fMge{S`G8Pe8y7!D@Apv799WK6AH9eNmR>5mOkZ*GJ&jl6+gAw%A6H0% z&07cd2e0ylEsU;FU^MFL4n4M>vc>>B;P>thJy5S{T=;nJ$l7p!UmH2b)Af-7Pc-Kh zRHTR%R2DR6FdDB~nA9;y%gVZLrALK)NX1QwFBr77Kk{g_)aHlfr4CF~_`h|b%gDc8 zY86A@6?1)f{IyA(-bhV!B8M=<*XmgN!%JIvJHpDz_>yQKYq_*ycEVdrZ1*{zQzDu- zSBLth7ah~GY;kC$;Yc7_nhWuEJmxRc7oTt6naylx_oVp}Y(u9S+C&0HG>)FlCcLtE z9Jctn`=7a8D>MGfjda@^i?I7V*jHCpiSXdB8!UvI1D>MC(z@|R<&>=-w;#0a38u)H zcm!+natJfC8KavkW0Hz~i|I~tuf9S0=5nO`EHgt=;-QrDX`?)ezP=CY(HdSkx4g&W zpFHQVPHyKa$oCZ&sey}%hp9btHd8n6*OZ`RK6BgenkxJ4Qzwq!vA-~#ibLNE_@-EE z{$bhdCz$u0OVH+r3yDhkV9{f4IlGlOUJLqy54oH~FAk|EP%1~2{8&+icYoT|lX&kA zO@B6^N=Q6y6W!_QP|OG{FlJpTZ!h!qvJ+FP8??4_+ALVXIg*(Jiqud$bKvE5>tIBz zv%!1I@l~tL^i-0wilMOK45cIb)GR$P`kQ-1K6Suhd&F-wYVy~N4bK=Ggr8>9Gdo$z zexCHDeOMe}q31Vx?z|;+&#Nk?Od{jNz2Y_SuPT!lcb!{~)mNFAanUP^cq!b?A?c*U zruRPADZ;girv<)aoN@D2M5EOq{y$M@rax=AyYyeg%A&WtkIRuaM@FDFt;6Tx%r+0D zD?F5Hw`qQg(}kS4fV!QT-9xO1*kpaX=kRWWb*Ja)vzBlDb$V@+vvz&&M6NdR@A^L` zir3R9(?`Se%Y2H$#ij78Kpn9_;F1qQ~gA+ScQ%v zhFdBqwqiuKWV;GvCy%d&IsmRlja`@cVL(IKN$M~c12fk;o;;^5&HDrq=%43FM%qiHnEM`>j@Xgw z5Q@`OsCvjzC1;MbR9hRrD6r}b3TqD77ngwD{0Of@Y+c2SJbYrs20AXdDc0$)b9>ce2f4o{Mj|+vAWeZ z&XD!$SB~fAZE2VAhQ$TXpTC+M2U6m{sW(V{(s^0zv~%2g%gfg6Pd$Rv?KjY5-6-4~ zd@e3_`N@=J&aa|~b!3muk}RZ&{Q+~0{L~ig#n0Q2o zpKWYQ9*y356jO;dqV@EJgU;(E{R%+)1iwHH%d?`c|5Q8FxA<8i~RAy#3i@cZ8vZr407t#RyqgveQKsQN4fh_l` zB-N^=z$6!)SZ;d+^%T3^JX=x=OS*_B`#WOlgf;u7coP5Pse~Jgv^py2RdvMjAj-5{ zhoYvTN@WM@Y`{%jQ+C*BOn#;v7?7xx;OHgTSsh6_tbCO>wNxC=_T4sQRbt!h6w*cC zt<34XRASI}8hdATs!Zq&o6f#pXszsWyjhOo$ge}T5SM>5uOP!DEw4vYi z@!VL1j~lwEyq~T5&v4h`WTVr>9(g_Q=~?f8qHvnFujV{|MS}5#LWN;h!-wl7ZaCUq z+UYUT{g^9|BxmUx#gW>!)!(k|zs=-+infe%2GhFKKicYoLT(`L5)(j&*C`VEvfgyQ z(@OuG@57c^K|Hna8@O@>jS$EQR*+~ZWw4SDs}(wsl!$~XHPiRkQq->ZJ21KL>~@fLtVpoatJwh8b0Ad$xQV_b2I3 zVx}&sH>t&I3p1aZ=59QcYk273W&>;5*ytU7>0L)7byFn3Vh<@LNk9H{+D~3zfw|)J z^B2Y(_j~v^k=%=29IXpWJVekpi{+Awcdu7&L$;y|1)V ztTdDW0CKkoStaKvzlNwEH<#>G3o|ZYI5SUjYRS!wJgltSxJ>SQdctDz$+Ee5ETBB* z9?j05eR3lQ+J4a4VyAadU8ZYzy)hS2jv&NzZa@pN_|e9&P{cB8_v9jxs?#v?j`M_6E(}VI`77WB}ZEys!M9Odfvj6qYZ!GS1UA(M?&H> z;eve@oJE;t{C&Ipcy7h;Dm73fojAu_`15U<{M+K^3ox<>aE~H_iP8TqL{_{w9SXVbtWa; z`mslLGqP(!?`OVIqz%J53j}}OiQ@X@DZ>_fIQDsFC1rZcD)VngjcZGto>ownrN7N| zw^Qn+C}wCL$4*rb4(?OMT)LeW34gp?*c@{hDrj*Xa_5D}LvSo4LTt}@KhHw7@QRgR zu7wFLdt9MAMRDGHvW+G5I3qV3?p2^!Qajy^)hz(*44pAUAADjrd zq8g7pR)K(M>RZRBa+}&e%21*=Sj9Yn0BS}?R{|i9z|OQ4v<^>TxyJyFym6SLaPYty z^sSPb(3~#eHDq^Il+~(9Kr6YGMZhQV(d}D*T7;R!GkVg63)(#31Zha`s6;QzFlAhg ztAn^A{75J7jk%|Q_Sw~>98MSa$zal9@_#mkPxL>x&Hm%i`}~`#1$fEYUH34&Mdv0m zJYDO4HGBy1Tkmss>{6~UtDo|~x2$7AXEqM~r#MUb%Aw?Niv zm;vp9qAdkSc-}W_WY}|?Vz(gvkMl))$y&#EwWW6?&1!UZ&5D{rRt)ilPQu&!IkubGixRFU81^jnyKP=(w>fjI()87jUaSh$?snfJ&fH`! z==J`mb>3h(Rw4HM-QH%s+cV3*apbzp?2H)TEvvN4_O=4n=8|Z(rr-VpBy|&_>#p|O zv?;*wtFZ8PlSHwduQoF|x2-W1RPk_${8GeVd=6Yl3swYl9z~0~w>VHSST%j}qcf8> zX)GFCsEGN5j@0)1mI%o!F+@!I15xx4`&VFoCK1Wg{wTGt~Q;KNGD>qSQ0=jL&=w|>%I6thUWi)=6ez+Bgt$4$l zb35_wNPd*BJ9?ARiA^L)`R|J?KZRxVD?XDPzHdj|QeI>3hu(#3J*%Bs!9=f<=3g!i z>%AowWec8cq74Rq%zxZ*(ahzO4U9=gPn<^%XpPMcR z2iS`Ig@yR1n{>Vm#SSl0`I1suX0L_8kj6u;9&VZ9blX!65>Vr9Y=po8U=_ zk{e_*I-PrdhPK7+C8ayGDIT%K7sn>{cI1{938#Ov;?!20;bCUR^`jb3j&qNfWNX?Nq=$`)Qo0Q;Riq5Y}QyqZ!6%?hJy6f+3nF9t7+H9wY?5LL`Qxxkh68V|5)oDYWuI zKvNRe$(FyL$@IbnTy>eMC<+`i!m?mD=*eVev5Y1&>S_Q9DVC2@k3hC$^ru9lG;ZM1 zC!%9Cn_wdeS6$EIt&jC%`->{KQcEM<6BLCl!&1o#Ar4=|@VC(ll^gu|fonOds>6<= z*UCjDV+SoHp>|2i)6b{HR|~VI`CtE6DI8oOr_KL|f}yBQxI)3$am3udsuXC3efg@D zu0+AZM(;Fo&re?Agl*698>2Bx51o+lgAyvMCheHJRuv{*+XBM`8#N`1zN0-w znpWkus)$+V8m3j_b&)&~hWNF6?BCKK!lfQ!EBBd%E8In!n?-Y$&xR9iCTna$b(P`6 z)~^3{p2R*4p_ZEfar%Fqs_?O0&%4msXzX+}@m)_0nemKG46_xhalG(1Yy7SlI@#Eo zYI*TxF_t_Mz*x>QU#KGxu=M!yqD&=A8nh$=L6gd^v0>ySk$@Y9ag+iy{Bh1nk=INQ zYm4TL<=s^(t4q8`a<~969X8bg-=Q*U3QxyME=u9_V`ZgOQ1|Pki}8ie>aheBse%hR zgS!1sOh_&u1ELyGaSmvja9j}TJuCR^j5K3kv)P-4DmI?xEUH)8&KnE*y0?R$B?*%j zXx56g^R1nZqemX{&Qc3;c^@Rn$zW&=WgA<+{TbGi`&k@FS|=Cqp8RYuQo51*wlSr; zzN6qNP1kzG=U(=1C&l}704rt&Dtg&`R^S}r%jM;TBiiaF=7B#((M7U83vDAIiI${J zca@8XB~RuV{AC}e4HEF=K=6~*O>Bt-B(jmKX_r!bp>U6O@B?-*1JHXkJ(Oy<)z1Lb zcl>p@7%42s55e(%D4>=Tc{Ttvw^s?QC??bOO7;|wA#BAUDcMD-hJbF1C{I-MP?T(` zZ5ExSzvDdkP6u)%`Ie<7=Z`AusW-Y#5US7!ea`O=hBb@pH@^LfnY?Z^p5QL^T4dA0 z)3tOC+m0>~EpF{f9d>dyp)F3p3%6QlwEp_+$`~D+Nm1Uah2B;PijiW={qqj$ zj1Bb7;}rC~kO%(f;dx#`pD%(|zI>?`bUuvO5`q@JyeLRt(l-yP+F7E2Y4EEge#p&m z_0Owph~OfNh>Lc&N6|4yN7&;X8>uS_1OTQ%G_n+`ouyGg8mUZHH0oG{f@b=B2*z&w%fbJhFKXdGjG|__n8>fq!O_*lz$`yWy)BG29g1lDm28#sq-A|S>Ia=d8sj9u zEGbx!!W5RE{mgvuLxRU?x7do8<$t1Znf5E(Oz&!Q+Lu~8p($9-4y9%+P3J~4d{kRG zc(wYl=X&WoZSzhl&of-BSe(ohXxzY~^Y7_1DNUU4nqScR%a0UPfI^&=v+rP)HVB;& zPfkG%NCvO{_85aQPAuzzciuhUji^&fp^B6h!~?5Cu9#UL5=sedTR9VMFiPB9@-i?c z{pdb1QibS#ys+z8OX(1n&6ho=~ZnGlocQVA
      ^?G)ZX$;6kkrU~N6=*Gel#+1MYM}_|NeDJYzN8WYvm$YWdcM;oPRpCCxt#< zCg(l9&wRbR{zwd!&KncscRNzg&)sFIl8DwDU%y<0h;jP(c z-!&)m=Q~}A_m)#6KT$``t|%{=8|-H!&0k=oXt@6iNuCkiWtzYE@A`0irt+V6iB+XU zlJJaRG@0Ka?2}zLW(0e>0eU(e$yjbD<0Z)L;vbej6?R73I2IwBTE(#`uuQvqcvp~? zI1Xbh2X=0V4rIedMe|^cqv6GHZXAf(C1I05uvivm7SI?mdGVq-aBZiFu=r&Olx<)t zcmRYt&Ua>B+V1E%u}GNN!pS(uSfGu1oALV_65BEMSg&7b8}P89vRL4|=qq><7}psF zQpD&Tfl_Wn;P;UrmA|4#B)=)C?owm$Nl)$a;EpV9#GI=@4SfRF7>%Hja0QWK#=vfV zcg8KlgV#%buP-k9Q%Sw)`RAgArx^pa!wfC|?avjIN!nGu+7|u!BaL^Wt3?;q6z_p` zM`Hbgjf6(zk<_+`N(r}Lb8gy2|8NaVDL_y^(1_S!;(64YSMP ze)tHvjc$9l7u?s;w%c$3ijE#~&P4`4O~IJb5gm&*@NC}YM8FloQ=c4i0NJud1*)rR=Yb1ZIC^WC^e?$=QUPzNxfhAXcRAF!E4zpWd0uh$+^Hn> z5t$4MW-qSgD6{f^xxh$CkF6vib+gu5t#$XS@)vTxxm`uVr!hrN==&l5xsCxNH5;9Qe<-fzY?f^iFd8)O~g;MF>K$eL)G zCk!G6ubG1N)4{vZVTrUHMA&ExU|M9VC#^^fDN|y=-5Ur(MrO{=P2>r94s~DxfESig zrX+w`V6`JF1XzPCXRNU;JwQuKLdsSx?n3D4LW+!>oW?gYb-0p;R^;>IvLlE3yK4t1TEAiA@$_GIiRt0-rXpagrUFpUm4wL#pfZm*vQKYmD-WyET9q6h=Z; z4NbbkO)jjbB%$(G_4&gC`wr4KO~?=f+SS5e7<#g>J+Ja(jHWjQbk;v?YCKzM^zaY- zRzBEgp%lf;7~&nB(!$aRt7&j@o2jkgX;3;5bzFWx0Vom(L~6^c6OWFEKRa+hk<{?j zMk7{fJ8nwjy7y9m4TOdL1%@)LWK~8*tj-CkPe=`H++?QK?|#O8#b4XxtF3cI*oO`s zF2`tgXXDg>0&zb5r*g~Z{|2&0u6Pa3@26Q8tB)TgrX9M2SiKgrXFR(^oFS+(oo#O2 zu7XC=V{fW+o)ZoC?BkB@9*e(YPA|m%{5!b+@24|pOo>x z@nOC7P1sZP;hV`sw!pXRwdeh}({bWvY0Dol6=%av<>beAY7|>svpTxY-7HV}i(bI- zH~9OlVc~?ZTtY(TS#GSv2H+qtFaiYvY*XXJW7?2K3J_sciC_;};R}W@+m!3n!4H?i z07s}CW-Z>2S~6*x_*n|Pz?yvY_6{pvQoeAsw3zVis>Nu{Whg}-rzh+A4_?)3F4{TY z<|a}_M;@v@MrE=^4`{V6| z3(=RPK=Er=|HWh8NxIHBVFs%niG+kPZo<^0ofC`eNjGYF7)^PyuoL}W9I{w z{okb)cUB4LTVCCQ>-+^K$Rt^4s__$EoYV|2Z3TW1zM6DC#(80!nx8C$E1hFksb4x z0cGNg@z(rg@qNrDaLSQLV0WvtMObgS>@@h9mX&fgOPb1wwJ1Nm%*s$4e3@yYAb%h`#t8J2-1E%{vOMPKkSbEF zzize1? zHhk-v{5w@#nCm^`a`y5>eK#^r43i_`S75~77LttL@_g(}<&_sGqYvR11^QF?r+&hqAh@dt z8fLUmR5UhrGzhJnI0QpA*N7l?tc^vk%<*ZLTAl(2R0;8iZ?uL9R3GQ5kXZxXaJi76 zNLg}65n+ronk;B;Ehi918Wl}NjC8`b6csdq8XTj%0%3b@99m}$-u2g;F2?R!hkKk7 zDa5~0l`7_H_~9f+!Mt_mnwdg#(q`0U9Sm_l$y9}g28L3)_`iIxanR!DPU+|<|9FDK zH2g3BJ947o>Qj$3UiZqJQ}U-E5%=Ej&w@Qh;@)tNZL1mdjJ+-}jeCLJvH57R_UT#t z>-Q;lMo&4Lgs@;8#E8-EDgo4N@!-cW_uaS7&qm4p&vSc)S-5Zj zXo#ng5->-jA6Lf;QHmcP5;{;}OpkXe=DL1`3B%xm1A$ZA>N-2Dq{$ z^+C-D^@x4yfIUCe7dkyr)1X6h86`>zpV2#GK2R2(TrkObSGlQGr`EQ|sL=4cRS&b# zrB)g|Uw@yTe;=gi6koL;CnuoOWD8J;xLDs+of(&XZ6EjNbvf;M;549q(Z9L1(~;6( zadZ1`HI`QVlT{8MEJLpa^ap*OhiZVbWM1TURXCdf9`HwKTb;iU4W9ag|H=UFDUQz+ zgDS1DMK<^Dfzj`BqsNC0~>+OBBTk^l)kSen(4J6gOJ>w_6w2NjJM_!Dsvk?EkC1J86KsYCnp z^8=l%SuL|JXUm%9vx=)6u4l?ws-@YdP47RS<}9K_nwO$EM|H#NS?ht2d!*1lKh!|2PBRVwrU*JdVZv_fhzo@(bNvGom}#3y}Dj5@D7coU2)mvX1y(YLf{c%e&hHJ0j}V;P-&}Hf$5L zGRF@Br%c&RQ-QR70;V*nSlNs7?51kJ7uCP0-LRH*L=|}!YIh7IPqb6(Z@E!dnp))Z z_eeMoE;C0T41`Kd5+n`$VF9HuoB#8DqhdAl>Bwp?#v`QdTV8u#I{jJfubHWe7t}0n zpG~6jJzhx*#1^d2!DFefKYU2Uk5Baquu=i_kQXsfO0DFW6_B_vcY6FndT{b1C;dFR zfL2I9S|}uu2EvAhF0+g?3x-K9s9RuezL_3s$dF z@_$`NeDNaILYMc6Z*+8C(feaLz&9}N$LI{tFp>o13H;rJfeztL&TyC!KL$ zx#ZqM+Il0O%Kaf&iL2tSDJ@?q#67Rc6zbKsHm^Guc;_-pb+0s192rwpZe* zeQKQz zg5q<+Y)qg$J2S3DR&$bsMe0?r&+VDXx%$rxZTKcd+`w8BjSX%|U#CTrE&gm~Xy8e#b*Kgi?G(!| z=8A$q5&KNhv}s7kaIDl+d)4Dk(RXWjcdTsO7E0E9_H^KJtoUld3V8%PZqO-Q7AFkZ z0|Fz#^SFw$=siZ!2g;nVW zry|gMdb(OQTM269`_=N<(tLKu$56#IUccV+x%7AG>+a~WEdn$NE#4wo-&`Dh$$#88 z^?{M16P}U3aYSh-lT|iJ&nGKz5N{liR(uXccD5BRrmH#~TimNldlTx@6oxd`+;gjH_&thX>)bLI}hYLvR z%M+xM;B_W5%9u=kk-?_KmnD|50=}CRmUTvti9iF%lZ5xyFlwMm&*N^eP(4fEb6D>K zpoIaBTNVL&RzExIQvS>_mFBnbruuc#d|SLcpjPZI+KeKfS%BS}FUP<)gFIIKW-CKXCD>5!(w@ zLS*f#jZ=o@@C6#fq>kjqrW_8dz{XLBatYLcM`X}BVrDggGE}iIC*vbdvk6GGY;Yz= zbv_ltFa|VObaaqk1=A0kH{>LgPsG%9LIM1KdZzZ7y(JJoru9!MF8a}sLXFdu0Rb?J zLV_nv*r4mj_FxJe&nz{l_QL2W70Q_or}_gKp-K&VCD6OXwd9<)Ry2sXKxg{K6ZZX< zFi`cf)7f3a*y+sJCypqqlcL{jyo-2lXyPlnN1Ak*PZD zA9h$fJy$LcM^Q?KiAv*bi$>3L**c-k3HWWYuq`j#Twbgpir@DY9H9tX5rO3juwbH< zK{yIPxbo1Auy8aK6p-Up6JE~Y?Ol@(f_O&?M(x{bc}Gwfd)1?t=M(%H%;l(O)@8Hc zQWnz|{H+@S{2HXS58V&$b&?>Gu60i);|mVxqKm0)lhOi}cgS02v9~N))>)D%{mIC{ zWt@F@cGxjMXt3I&cR`?3;~{xTL$;W^-&&q_Sv0yCeO0nN8j8hY*17x{l4K&2BzgJH zjWF%q_4~6z!{Kq(5}!-IrY_u#l|F+r=@JIfotDNek%`rP>(A1?A3lu38=bKcCk(2a zKzasBx!d<}xm1_ce49h28aA1!8l!ammBX4I%x#dEb~Ho6=c*2=OAu%*_;e*D#D zulH5(B(x7+-Q0MFhTrclFL-4=uX<=M@2*T4Wv#AhhE3|Uw&U2EGqP&-R3~85>)Coi zByRfAehW{hxlpvRt!3Phqv#0_LYHL9ATX3RF3v|7l6oy*3t5kO@>UdCYpnb4oKp9W zb8cVK1dMt0u*?hiS>C;Uk?3K%-t}wjEipo{`#({5>Y<%`CglRE~)8RmO8^x%M}0FXhlV$TI|uY#7kWp*%xg z%A>M1W5^pa`)E8xDr|d9bQA#WnxNR!d7&4<$f2BuB2Mdx7qdd5hGQV% z00F4AQFEfO-dhu8h>~59c!F6E-X|q+BjS^Rm6Jtfm7qcmEAV;WTslLkKs+-OabX5w zw!oJGN%j}I3#%+QXY%|C(p#E8$>QzO%)T4#Q4MH*NBq^De&xw&k|J23lLua#u1M%) z7r_%7jC@!;m~yIY?Ik~bGD&luN}U#bO+)_fGB??*@~K;Ix%3SFXZn~QtA#ty5m#iBASLxX0aAG9M3m~I%gIYzN%Xog>lS_et0{1=^{Uqx-wQ7vg?b~a;GOt zRL8>CB*Uj6ROb@MC&mJx7?Z4qJOCDG>2m?X;WoqKiV8-NCRVusOw?Yuma?*OIRcUP zZBmrWk)mY}AN0T<6ZZ;$CX^k&`A#E?pXIFVv(W{?^UNUkKt%{HQwMf7wLMod@^kG7 zqqur8C+4IRjg##Dt9hT~k0)ZDg*|U_DZQ#ZwFD@SNBNoT((-(r28wJvDK-~15|%sa z_c@H|<$rw0y_?^$U`9W@rE9iWTakLEu#iS!lj$&Fg!g zN6`GsKAV-dFHT4i>zCXY^ES^Ok3{<4h&PTg17_tI=lO_D z4@eabn8P#hwQiRnK`LzXoQ_iFebkvZBqDgVVSRbpXbYRs67&3<%Tv*w0Y~`wM9pDUiF{)9d8#+VVm|L!+QO`&U zotLD#;*+)~8)7aWJ(Ze#$?-eIeP^e6KCLs&Mvo79jSI_L&G(46)ql1%{(iLgd(^X5 z*}X5HuUpqN-FJ`kziqns-KNv&QNfd?)aM)#Oo7q#y%u{tCaQC$${~g;1;$vWh9a$I z6p_X%k)lMAfCE@uK{3>SF`y3`AIC(a5yQ~IOlnm)s3L+pU{sL3ObLLABiVNlI7#=> zbPWjJs`aYlmXNgyeI<+3oPbayYEmRBc0!(Ym5TXh!yzOc_DqkgwaUVAN82io!v=9? zSOxnL@>7-q44^8+_3`kkCy`3xr0aBaqbQF~BhTb<|6`24#8xvUCJwl0rg;)+NLpQY z3Ds3))oDEyas45}e#vMQiMa9cUEC|68sx zoZjCL=GHg5=XB0t?>nXSBMz5QmkJ6BjUHCH3SNbZRsAY8Q@%BeUo_-?Fu_qcgyb+h zKLHPB9RQ{rk>(77Mi7_a&}2{-FmNj{02w$K0TW2otS`jk2_gxsH>8kYXuu9ZN=Kf+ z$xs<}sss%&a~Ps@vV{Ny8PZ?O{wlN@`*|8zMNx${g)dX7QgyKAZ450X-vG0gvez0i zX~duy1dR~!Or21j>xMKq#(;G|J7bsP{VNI>;*O+utafmr{B%t9R|ycIg$0IakRz}$ zxLUF9-{ibXvF1DG>EygeDQ}3`#41Zat}85C&Fh=%e$rmfx?ptv}brKc&B?lO!HB7p=*kNgOWsglRQH$~Dt5FmPNk0V6u3^e_yA z0)hm?FbD?}34+JzgrOSrF(gF=3J+O^pwNX9UF4WI6|K6f@#j%dzyg{ifUyC#7PvXf z-dyA$08~w_G<6FL_>IZT`!|Z$KQCCR>rqXWRp?qxRn$x-w580ctzg@b)1)6o_?42u znyERM5aLv_bf!y+*xp1TZKT9xm%ASCRf^-8Y7(wh8nKC7enD%rR5Ndx8`&btw`g%= zUA3{j&ICL`Z_Fpyg#sH>p1p0Fc$>9r>q`Aeoag4awry>|u6!sMxB373;souF_!xE0 z1Gsx|`YfrycMonJeO)*X;qA-bwu4~oZ&y(Cm|i)5*{Mo~ay5Dl3M1(-+zn8YZUU=o-r2!MwH2v|rGr4n2Z zNHR%&_X-WU3ndKI@AiRH`*Jk*W#kJ{NW|;c^`Mxh*`$*SJ zSIL}9cu#~`nn19E*f(r<-frVaFe$4`_l3V;;~TM>8@xT=U>HCDr+@!jH=G4J?I|+! zD=_f0Hz=+OfMyqo1`dFr(6qyVJj1~#FnTcH0}zEq3?&`ILL`WQ@5b@fs#t zrf?7`6c9iG3%bmS8C8)7;F${WM*u;MWwuvIcSNJ``~b+BDhnr5w#(RZr>1C~s@Rxg z!qAH`Ume7z7_W{OdK2?q4t!ln%b~v9B{=t~AJWG|>kza4j(0 zZZV)3FhqJVJQy&rUIqt(MBy-GV8A{O0f3+=I5tBC&{{BU0~D)E=2aRquC=Ow*VQDL zLo`Bqp_@S)KyMUXq&A^)E%fPC?A79GkP2q6HtPB>=4iwz*P9||&_u11tB7(V7o_CM zm|;NSEviS}1G8=nu>ZF2NML=IUubCDW*{uM#LoM zA`hk*gvLAq#taGr0P%yw;e()2fZ#!jq8i;vP%ut38?jfEx@_67t3z>Rt5m+~S`$*_ zyiKYuA#zC<{J-fBbz53Wdm%Yf)rVaODi-9jMatb^1|ZxQ^Fn}N3RhPqr8P|DEG!2x zGW0=jbOg4chfZU$X0Y8{`BViAQCp3{63Kh*07>t=^OQ3;rSZ5Tc1|6o?xNj5OJG=freZc3?oKDi6ER%8dMlOEMoEW>Ca`5imPrZ5JTn$YL}H3gQ^??XWDZ_1N|5U2 zh|!4%336>giUlwNzz9sB@K7flfQ|lDw~W7=t_lbVCM0ab0v#eOTsfJH7_JcD(iS7~ zFa*m7Ni@H4CDgCm&x~F#QuI=s7!VSa6euBb+%SRwqJsvRabf{w@-U-<1w6%>m!b=r zseyvoda-4H8+ZBJ_}h`=FQ34=0Kr2+RQR9;BKIH>kQktYp^=~f0C^IuL!<1+8!DGH zHo}m}bSe_d0b7s?x$l2G`QHCKujg>)u;>3jpZ?R(7`)F@UZ~`76`i%rAahPR`1YJ(nvpYs!Xp_zlEzuHDfV|hm0Gf!~;{AVa0%~q*WdQ0VEZ03M7ru zd5L9;($3-XJ0%Cf0Tjf>4GxYNAXw;fb0jE$0~x%d|NsC0`pk0K1cn1{$oRFGqMNWc!V7U-BQ+A4$ z|NG(uSAYqmgi{7@AOkS)%5cr#09)aONFBTY14%7ugSUVIW*rfLt#?;DDxQo!4mNNb z$q&k!%+Ft#tD_;u8BFe0>`m6k24tW!m`una_QwLS=n=+-YCSM7((U)4mQ34|Wid@n zKbpED4d@sgn>~fnAna<|6fPunhI1V%}4ka>ifWTm=YLASD0s~!A zCWHQ7(%>K@TPRSYhMa~dv(4)KZA5@QL{f8*20)r;>82zbF>O?>D`BVgGT+sa6?Y@= z?xM1HmRO)GDM>QNp|2>j^8ZTVs48+%U+UFdQRTl6$6|Jv6nYf^#-HfqT5|3Gpu3{d zJ=E;IL0PJrwJ0gZ?5X;bsIqZ75=z;9E)uHJr#an41kCk&Q96-o8xe^M`x$hzl-uNjW+j$3{`FaP+%-!( zUme6RMC#K+@S1Gp_~m*}NnWKc_0CG}cE<6B<#O6<^=xDN&vmNvJ$@f+AN_vutDaf% zui8qF>f=L$W>^qnW~W4OWP@bF#DHOfut2a9iKqe%F$M6h8ETfSGr%nNXoM}-1bb5! zR`Mt#(xYm^{k11)%9Kp0_f36@c6?5~pfh`gcvnT=k8 z=jBi3BsXs4uH1@s{IfxRPp|e&+Ju)U(__d0VfBx0icc zC6IV%u|ek;pfIb9sJLZHfaxh^y(0i7Fa#JBPAU#j1q>zG5EC$K0Z^A^OdwIf=xKYm zMv|~XAtat^IRnZW+E%s3bg|i)gpSkt;>jr>Y5CWMe5>Z#?Y+t`(q4vQ(@-rGk2rc0 zmEKCHD!=z?P0`N8@5CRA@4RmG^;vghJj;}oCuMLnqEU_dwYQ)0&Kj+69J18~jaS`F zv&zmE>u#TuR2g!$nrdp7E$h1}_90}ldd?5ZmX8LEY(4ivJ@l#8a+DhryS4^kQvJ<_o#ua3nu zN6o5jK>z#V1VoSbBy7@yZ+mj#O{!pP4{ls(y-W>Z?ZbUHX~CDhxq$Uwc(N{Gs~cRK zzI6{3+j9=>noi3NS$jX+G=xth%D#B=?Qvl|zG+DBA@1@s>K5dO60crXx_jl1s>^7U zwXuspiCx~?tH}A@vwh+`gAzl!U>^nRdooIO*a!#|EUYCcz|$fWLIx=KC*DS8Be-?hd-(pIE2z7}lMiQjBYv2s0+9s3Yw zGcFSBeqd>1hS%MRhaytUZZf$u9(p(77X=wqa1ykudLZFPxI$`x^;Hc-lw)8tBE`b7 zk~_CL;e%}Viy4KD&T6;J$qlB^HEP=$ZhJ}e^SXw}`mOs&vp<_o6?XRW!GeJndY;+(>vYwx@!Bzu_Zn;uYG-EU)yl@z&(c(JMpgfTlsc9AM-{`8G^zJ zh-S%ERaE3>>JBm`HDxZO0S?L{b{uzwh|#w<_Aa2T-J+?hD;_kpw|&`!3c_GJGNq{8 zmt}XF)57FBtl@JuB^h~IV#HWBOw?qJ5kVUB$itbFQ%p74{G}^S6d~DgRF{-2_dp>G ztms-TL~^dzpC}VZx3OO}tKK%Gm6J2hqEa{I&06tQRWb%t;}naiFWta_C7L%_k*`g- zOC(p+Y+!G1%_&%qaY(SYhZpm`#o08YjPmW+hqy5_O=>-}yFuT_-gTUA4Zf{U_wTAx z?y)hCF5X2y*E! zOQ;})jtTru6{xl`_}n}Vvw=LGvC@VYgfM*O^zB0NnU`J%an4~Z(7EQl$meF9%hr4 z0?PZg%b}D;)`kdkVx8FfQMWe}GWf+q)g;vXiZrypFGqTx<>ytYrp}=~px<$>)S)^G0*KV73ZPY3| zmeFfya3|fP>ONvt^5a#B9u{d6e)X4F_WRy(xH`NvrPIv4+W(E2o6Y=0h7JrP6a*!r zDQj4ij>Y?rQY8QT;skh)cIIr;gD-n>*X_!HVef8RxwTFVz3t11v#HgGy}8a2hXb7s zbUDV6l&Vr*+J3G`V8t^@2}qn(DdMl7Ng;4lubLvDy2o2i9wW8_F!4b$7D$35-!Yd( z-EvT_Rl|x(s>bv7WnosFPgP328I0&nuGkO73XR1b4A5bJq&F;8PqMT^g8CDgJW@kf z=Gu2=#~D~2N2`0C9YvFIbmYqYOz!M&D&JQXS9=!}uDh4CHmR!_hW*u{)(?daG%7~T zXU#Qx<5i~dnoWA|H_r1<<3q=;v7F6v&sBYygyUx0&(ugLInNoid8#{CQ3yjti=fK> zorhwZKNYc)h{K_ZB9Me1W?178!2}G~q%5$H0~krw=(2@mp0l1M_33UxN3i-SR*zIc zz_*3Br}->Lk6PL2dLM~K@`)0nFw22(5_8a#G9Ju`Q6f27OZ%ibmKzsSz-z^_kXON~ z+masE*nPiekviWUT#a_8a)DJ_dV?+MNQ*Ht?XBD>m)#=7)H!Q*eO@a}&5`Ggc-YRL z=9R3ufp^l@o2`6H-A@C1mvea5n-$db@geT^gFSpoXI{VVcxJUm)bCz{@5kFhKgt?? zL9n3FoJ}i-mA#V)E=2f*sV0u$sMz6A&Q4j>xpa{@P(uJy1BC)*nI=GL!WLU$4%E>h zPm2VxN74FSi4dfq&vS8Ly|cHhBtww@5_M5LZ$ln8jU-}7nU?{;B<2xJbRp3WBB1?E zmv$8LrM_#V*GhIL$Fh*tg%yqp9;Zbom*2HjRSpuRP^V|Umo|BMX;o%oGgbRD$zyGn zk=azZZd$`GT%t(s8|_;e)N0Jz1{61$wc*;aVZC_=4f1NObfoe}r74SEw0pd1?TMpW zl*2^TG0)fH9T@B2{b>*Y24Tt(TpFV|qE9@M;;wdD6U8Wg5=fN=+?4~yW}Ar-?3yIP z!WoK!+;av&?p=r>k~xakX`zB~sL--{b1^8@q>vNfa#<+@6-;vnL8#`XOc1fsVV|dx zn0O7r=u!#tjm-=^4%KuuT~Tit8Q$F>eO*BwE2c}SqvtOoxkr5UQ92sY1kNC9 z&Xtv(5}#L!`^{SB4I#tJyGO-p>W))e;|*=ptO!u=Jl^wtS9f=7(jUb3rLnIp)U+$h zT>loezVod`=~cm&tXa<@9!=@~p#T6x(Wo7;azVxk3IaXdt5hK1w8)3Z;DM#G#t1hO5Ez6HM{qt`UrHDC&_QHADGB6$xhtDYF#)Z<%gu zM~QdsjH&o-t~2eg6^_OK```q&hjz4TR4WgAaMes&m0|C08fA%63_b0`eln^-hrPIJ zcrw<_^UFJ)aN7n?wQIfO%H3_@x_i%?eQR09C*D2c;?|3cQt|6w3K%+k0?;|r0?%R) zwgtioQ`2QsZ?2UJ1RgW|3P#g?nf#S{ zolcZxh=wW<^NkiE=U{%WN@SX&O5tb*IE{(Qpctkg|5p-Vs3{I8N09#(AxaPu*b;%# zAL`}>5hrXqki>)~dA>{B-m9f$a9WY<@y%TE^DWt;F+ZEKMT2H%(9`ZH z`nKjfbjExg;>dwt2tf}rVO zc#PAG7dDATp)9Xs7i7PpBZ5K>0TJK^uH!%A7e8xZBpp*REKS*8N?gf#-&>1f5DioS zT^J@2NkQDxO6i)vmDWZf_CXxFZ@nemEWP$T{3 zyQcL`Ry9nA$chexj{`!8D5K@hAa7xRzx}tp3UH7{%t-k)#U2Gi+rgp}HGw7zcW5eZ zo1uoMvf)dW&fS))!4+~`22744$B=^k2P(QEU_qBFVP*?~H%LHo%{agV4;mE-`bw1A zX$XqDS9^wz;Np{sB-7n!lOCK&;*SehPz3@Ii3$^m+!7lPPP7F8S}>#muU34-6c9oP zVhIc!0LxkC+!=i;;HgT-EWu7A&k$)3^)rJMeq9)pY0{i_=W0KfqB7_%W?v1yF-cVY zs~A&Cq*1TNg6yVKju9A*x*OD($i7n?#{Fz)^O~LRSL0Q2$CYNO>F?IO>yH`Bz ze<^KcYdaNk%e&`0&FB2SMEK`63zIfM?Ke*7O$xZnLz_KIXv3zJ&{!-)+^yO$1d1u( zH0FT86F-DTrAQev1q?wlHWv9`H%B$zPh?gRAb8C^d7d-}Dvl1RlL-$s(&d)ub3|a9 z5P(TeQ=q0q2GF3Sgck7cCOCF z>F8ixUa2dW<;Q-K%{8cIdPNzglWI3st{*FxOKMr%QuVB_#%t=`YV=vrSe0kn`P|PO zwRV3xwsW`6Rn`3aV+w4uu~!fO`{D%u5BOMV(t|m}aS@JsP-hr!AX%G84QDOG(Z3G!Pn+;t-I{j+StEGxY~( z0wI5qIZH*Ec%!J4Kq_YlKxXbkj-6bgOm#X@Ht2-OeiG>m*%OAKMq?=Cp0uI-Z(-}zVCRCaIZoQSls_PIW~@uA#Uz(w zQXHo-(cw}7>&1^E>z~_7B&Ev&EJKLX;U=pP1QjM#gk}j4 z74*IVOXaZL#tPlkNu(|3E$UvVFx?V#qAUf(GBp7VNjedQ*-2*|+(1AjgGNbYZZ0#7 zs;NN=YlvQ@FfxlYIWsG9-zRbpOr}2!KG$7jn; z_D6=^q!jM7+@7gJqa2sR)DlR8Re(hnunYCT!ztcWHHY_wOA4@!lQQ`<<+B<@NP% zJo&z3zIXS%T{?BbM;KX@IZY(*^;Kw~0aGYOFj=rOVDgf9N>mXDOc1PS&9JGlm4Lp? z`JO&2A!n8p-J|Z>^H<8krw^klu#iRDO+?R6X8}#0rbhabg+f>(?!nh9Fmv5E<#Z$x zR{>ms$T1BTnV`4?r(lC8Qm0V1?byUOq=C(VDAW^-8sM=E6T-g%u@E7?o-vn4QF4s>tU7|a`r!8c-PnG`0u#qy1T-geg5NT46T+h zXyXc#v0zc3+5JoG2t*tdu(W(3u_~QJMxsmf%m*kYp{l9^Af;)>r7g)DN&uh_bBhX7 z5>PO}I9rAF=m$Ens0znoP82qV41sbzx|K+_Nm}ec@d#nTT(S3_Qv0~k z2&_hSn#=&J}N6)Vlr`@WYljoqzt}|NG(u>ks$CWYL3o!*Kg7x-e@PZXZdBL=EFD z!~`{HfxKn8tox3;Gmd|jvCk{JyZ?^<(7040L^^DI!30P8*oM4g3r4nFYZ3%fBT5D5 zC>BL#$P_3hPg;oHV8YG=MqVrtLDQ(RE+fMrVPi#8rHU99;2~=~OXt}Hsm!5QOS>C@ zUvliVrJ$|v3^Nf=CtdVx4+&6hfz~flL$SD8l%i?`6YUHY_>eQHJc~_r35BIGgHq6I z0eM7d6dWPJ;;xBHfE<^avXDyUY%A>PbQ)dj+roEJEdac;K1l?*WWjy74Z`{uHZ^Jyf zpXY{j-0j+!Yn#itepg8-1jt6n+Tw%gsae+{_AzCnH6t`BVF-zc1P2PBISkSebx~q0 zDs2FURD3ZG17}uXhNqN9dI@l$^`Ai1l1Vp9c&rJ1EothRsW50D7&U_qvlw6t?M-cVW49qwplIHI*eb*R$-s^k(H_rbrl&iWji{F-a=~iP0sxZfpIGHr?gft8mfT1A9P+;o<#XHj4Z8~o#nfsidHoEkh>cwiMVVnx3%Dj$skG($nN(bY-_gs$ar zGP@ZY@sr-u+-Hr*ZVKNmX%c8*>Bn#*OPzLUt;l0??onBi$>t}ZW}hU#R+3Wy&rZu_ z@|i7Z6-!g{?6RfGX4X@bm-F3v3Tg^Fzq=SrU+wME+|GX+b!ty)cH^%<)mof6e2Rh#4ysO5D12+GsyL>#q!`t92YJW&soJX zbJ}H3^yLgvRU((p-n9lhF-iE>K3_clT!GyB3s*%lEsOcmMn11ndv@*=EoKc++t9jOq|?8g5_Z zcRUT_EyL|Dr@_2sxLEJF=ikdLe;t40&*$ZK3zG@aM|P^Dl7Wih)sC zQn3LHs?7Zj9+noo5HX^ngRZ-aO7ftUoT0kH%2c!+W=e~4298-)(ZOYf@myvB^eLpB zs`ODM{ClEeBy}wECCXx;k+>}OMN0xjoqT5CwGD6_rG=b;tw`x#Cx+|wB7bEpq7_Eh zF`%2FkiU)D`-1C6C~Uy+x5?Cu$m5h#aVmVQOQV%3-`LJ|Wl^hjH5kH8E}ztAlM{H} z*6&-+g8e@wnyoP%&kwPk{ObqB1LW)y8@4Cz=y5ChHKm+}8=3Mk#bB6GL2-!#35W{- zDyj$#617ogMnWXb!6<0Rj>A+WD@XQJ!z~I^;lu%aaF49s290Qq)QtZ0Syu@e9ySkcc?Wp$;5j=YLX#C{V#%x5f}|yCP&Ri6M&U=?uas z+)1-7SSB?9C{uja-^JA}u>M36^}ukQS}AocxCNZbTZ9ECu}cim--j{eHzTtqh9tSh zrl9T5Pr$EcT;*!gihB0$_Pjd_o8^grEYe0Jb-7C$cIIg%vdPQa&U+kX^SIH~r_R+K zPW^AY;Gl5gMHawt>c_$iE4zDNqMyB*)+PrV7#%clg9u=uf+>4FXdz%&IA+|P zqG60-YdVTH>;*y%a}P~WVU>|0P6lF02(9Q0J6MoGP?yni+e>p80*!zR@+`DpDx5+W zO<)O@y@CWqWg>#AT4GpPW@H%zyWJ-#`)G*Xlz;tsg`0P!vs|RH zUpbop%<;5x*MS_zP_Ndb2pA+VQfzsXN@O4!aKQr<@H4~}a?I6*v|{4`0#u0NU64@g zC@(x1#}zoh5K5m3UXi2&1OOr7Qka;X0P~{~{SIIeXdqHZ07WI%(i)nGgdziA;DJ?8 zl;vcJT+iNeA`PH=L4*Mj9@DH?0RvDH@27GBReEI&6yYZ6YaMFkzvC1 zcv+itaAqABcJ!WsmBH;|hdGGEKM{XtAG+6N+Rnw=Zed=u)ilM+R9uwN{FYG}nwD6Z zotH|i(n@MXezjSb{!hw!dHLyWX$9=7O-rdLWpTWzV{`xe;soxG_#j@-gP6;3|BQ+N zZy9bLQGG%U;|;^rt>^)~Ww_aMcD~hI<-5IprmSUSKK`=*)*8nryZ3gNOi}tfaCdK@K{BA(CsX^d!N`FC|0d=#m9ZHcIHywo0MK zPP$R)x1Fhi*<^yB3~-~$n;uU? z@;v9Yh3j9I81m*5d0}GKT*E89s3-^q4i6h*3=$je)85vLd{IbIGX`TYR5M+X0dawV zfdT_T&3z`!3>=DKG}Bq}3KcMekQNefFBkpBuP~wj!h(QAB4wkpJ{t`Xa-rFVPK5Qm zmw{9x@}q-Gs?u9y0a7(Xk@Z96z=KLqw44FRK{Gs;Abg<{0_AB<1(B$;25XM$k&1$Z zRAHjPEKtT7E7#LAiZfX}t(e2o8504CIWN=OQW=WMdiatDW;){-l;RI7wK+gFT<5-C3~NNFtvVu8m6U-^O6~TERLn@@vSP>@XxxTueo+V zUl#$^77wUCWHT@uNkIHt)RLMiOA0MrYG%gD;L|gjEcNO?EKJbEH7%M4ruw2voL6dwy6n*#7tolB2|~FKw$HP6(MyO^Ey)& zF0nw@RA~5T0(%yDC){KMBl6fr_bEzLZGtg0=1C~bC6_D)O(A9wt=J$NHDApYA>lEX zq6W7AN2D|nCmJ_uH7<+iH!FFcXuUkIDofP*&R42geC~3+Nhq&Whvf9sl(nZZw=b4c z!(5e7Rfnop%ES#c_fpDh!e(U@xWeMFO`0n4D{`pLzZz@U+T`^$d%e$ja~l7DyR)9T z%zMsje~$N`{cO!V>2o7g^o~omD||M_yKB1?xQ${c%vAyF2IwGdAR%*gdICo>a1cW& zk^qbwnFx3^93G?4oHP$WLtY9YR=bNqT8xb`kzb0{N1sscWTsUewJ)2spc8Lra*;!o1YQia)RVn@YjJXriDla%-e)4DQAmVumCD>`OSF z=~~33Oey<%cK=J~f(8JmUP} z{TyME!PjHP#ex}i1ZH!Qhr}iq3K$s{VuNT1d|}avn!>>0s;dkdbEb->Fs8Jo!UI4m zu-j@1H0UA|C`BnVjYnWCA%{O>VVPbV0U9SX^9`gpG%|n^T|Y!=qcITd@&!$xz{!$T zi2}qW?z6y{$g2gt=piB~6f#YtBa~ZLGIYP`EhAEqW~Vxsw>SaGZjpBE;xPtm7>8xg zBmq@N-q(63R$ECNiq&~1p!lRd|Kl-)t2wJP6)MtOy>>|jR+nn5cEq;!5^2dq_7r!r zo2yoy<-0oHWiz&@r8#ap^R_GV?qAju)6?1C!!2WuH+;Z!*@i8krDwoVO;>yRDijZy z38rd*L8y>NUlkfKT4ynk@D#>ikSMIcptS4<0tJC)OAS~vKx^tgaFmZmazV<7js_N6 zm2_DXV6p%R0A!`+EqRJ?3gbLAC@h(N3yuj93rtf>0k!lLUd_okowh+UF9Rmd(x^~C zAc+!y$aSWp{CT=R%R$2$qGO_Js4rL*t)ts!VQk^py#BK%;sS)p9vXQRMe2ye;5;J` z%-yDQW;+n<1A5$A#cQ+I@W)wlckIiSDU)@}O z<`n$yJhfZ!-}iWTK33gd-R!c@pU>z2|Ns9!|EX!zKtnQfyw?d+464q)!ZZL3z=M!5 z{j?Sy0!P7x;Q(+T)&fT|LzKd^Pyz`lGf0FB1f`)ylDNzbr5WN5kRE`bCmIa!+9@7H z3xh!tUT_?kh(Vwb5QOsdgN!iE4jt_Z4QUF7f;7P*9CSipQ320r49(>Q2C>meeJ%GT zI0(NdZI{#NhZPNJ0OGR6-4u5V*!i?ZA6cd_N4eivjK&LqW$-*XIRWzZcipy@zw}cN zZ0x?Jnc4^*+p(waVp)wQt;*@;R;aD>3wNYY=6Ktt=33A1=US6|?=tQE|NG(u=a2W7 zWln>c!*KbmslanMZXivSI1XzK#1=AV0leY3=UemU^1`*=?<{iWskx4~|DJvS|NVde z{_lJOj*z%0$VvkQf=sf-J)A7VMw1f^3``R+&?v&eg8&D{L;wJp09>G8Ap$xtP$Uo0@e6EWfzNkF+_2{uq=0Rth3MU?|4@>Z8%X%f+4uEHN9P+)mb z6cYw9pbCVOBLg5DbfJ1m3Zip{xsg;H3Byw`C>JvcMJOeGD%RPpIL)I*61to|@I*F= zu7f*MSJjlNyW3^9a$4)C<+a(EtCck0!xQinx=${4VTi^T$SSB^=<1ckKOarY$12P+^@)E_10;h%?P-3A3MgSyp9u-FOK!qj0|SJQNjDB80CC&Z&6+(ocCeA^ z!rfq0uW~6_GYwv>p_jWbYzZE682yIPx=UYnb$S4n=I%u3@q**hsCNxLv8jpahg#;N z*RZ=%f0*Y>yIq!1QsGv2S8iRgQwsKX_xrwccxu)aX>k9}UC-vbzT^M<|JVQi>shJl zyWtlZWi=`R8T)y^2pHtKiwcOt%p|A;DlAMP7zPIx1B{eZyy(>K0En0OdLd}m+IZz8UG<6YDl`&4ttt9e!EYuLa z<-J(X%JON{Qa8=W;0%}NQ(=IwD@a(u2r=OVpR*tf0I&>%;+hKWu|y^d&(Bn|G2W(; zr2d_Gsg?{4Y0obrH>DuDvuyF<_f*AMY4fO%p+lps-lF(`OtLIViTl?F2 z^5=bXz6Oh{08wOp9!xquWQ$jZaRj?5H+ zRfqJ4Mwl3N0!#LG$jt0us(Cz7Fj)y=x5`*E6mes1ka ztT$%AcdONFVfk|YedqTL?;QUfZ~NcZa_+g!&AWLYf_uNx1O%Hf9&N-~p4vw(5C8k( z1m%zR<7Cc*czbZ+i#gD57;Yn3lQIr#4a8Zprh&a-xERoeWbiRTtj57}4VKI{Zww@v zTp(eP*oX*B&`a=P6zKp2DvLBP08om73;_^IG&53UA_OFiGG!JxL`*w_JP^S$0H!e| z45>vxVo!{LGs8upn2?}QX1#i|lL{`PMXP!NjA0Zs0TV>VAYjXs6D@1}4HB1y{{Z`-6WRS!^D1n`56`9#f` z&;E$q#sx`C93BfYVsi~IFi|r-7y&C8L8+5oJ^79ZNQl7@g8?5F47A0JfJKuK5sCx^ z6&hK@_BO~$t^ffBKo}rKBw(_jK|vWcXE>6~d9yBk06=ErNyLvDp~P3qCSXN{N2ds| zV%iq?Nm!tk5`>@#REQD^VTUZ%224f_08n#HOiE?WSCyPOovmYgE@$2E40)aHW4rfff4^4^a~^*C|NoEwfB*2c zF3zt`)DS%75F`N^b(9rU8IPiVb6KK7<}eNbhQonC5KzFyP;ivQK_XzVKoy^a4FXAs z5EU;pNFkt@A%KHG2t#1uBna6+sunWS5S*&>Kd+#06lSw869K}_E`fe*vWBu=6?Te5 zjVuVbAT5Xx5jK9lN`N3bNDnnU6ftRsK(dumRU*}i9TT|=2Z+hlsa?B^IgtpHZQFp^ zLgkV}mYH>SX$?l%;$TDfB5^pyG@efy$t>O{5-|D(}ENN$3tI0zk0 zJF$f6q7s++isWwyT6wnBUViqC=BY?wQsTv|AB8E@1I2KJ=oo!D*@R!kcLG;nN zY_>T&D1tW)z>if)9IAFn0p8A}rzpk}xtdv3G|c95+SjQq-NyeZ>RHDb>lZa<#eDDg zyx;%(;soZ8_m5glgP6l`_-vWLZ#Zrs8D}&OXAQ&NGN%E|;kfsCbDy6(-0WEWn0s7PVpFjN3x z5IYhHc_CFG6qG^|Rqjmk6NrM7#i=1K@4Ganj9l#)fgF!N>f_|N)*Efu`E&}E< zy(~r$G@%d~t^g|sF^kzAqOvy^B4zD(lI|Vb^AEK7RHi_-9;vou%B61Gs}NmI44Hz` zKCneRYB`VHwO)RDUpFtac3(X#)w>vF${zRcXZ5>&?vfgTVs|fPwVeJ}xU?2fP63{*_x|jN?C%S=_g)oj|UT{NGhoc7NB)C~^o*G|C zu#b@jTLq{aJb$f9*1U@q+WX$+2BC)KUM~StXGvA&l*S*&;su_+D3@+-SIN5>!Lqwo zu2EW`vv0b!z1GVNYt!ZT`-RP8cN;k8|IUB!d*zEe?=i>qzJK$7|NsC0|Nn2XSAW{I zX+}L%ZE|O>`fpr^I3g8BH{e4UE;82hGaonwLoO}=jEDrn#s;7UVS&rMwt_%~33diV zFC#`aOfwH6oYa(2auU$!po!dELdv9>e+ZTf28l!tte{be>R`NF~{oUC!!rtF^)c@qC={c4o?0o z4JKwEIa`#ltKI<9EP9-_qV6)4wG?X;67?Tjw9wSLKb3h^$y5Q1>=~Bq%O!Y4V!GVA zUn|v#nC1E&>d*FBO;+bC^LSXd-PGSZpD^aH*TY=q;W_93`{(cfU;qFA_|tN)_9)ZA zqYw-=N29%oHGY#$vN}X#ICL<;G$1l#qd;6SRC7-xGZT;@0RVx8hXn=#rkw#8>K9xN zIPswi2LU_;RCQ9Q=7K^Y$$Icz!(%+ zK}!r4T?~TAmT=PmC`f=}Ak`{yh6bwR$d=`ZB8g`NA~xhG+Tz`{D%cfCwaIO$Bct0R&4qz^&u}C%Q948NGlF6T_%OH=qGQYR(n%pUz@p zlME_hjVC*w($vc>^2V*>g>B>9DS4~=i$R4mlw?6zd;NkWsK-=IJSaJ^;u-{3z=QBW zNEHOs4}pe8#JXT4VTNGguyYY$AjW_Uv^>Fr9>YHfGGikRr7!^%tV|+dKm*~$#Que-F-t)@|2JBPA62A7$Of1Rc5uH`F zUj6vi7=L-L_h0|}|CY-w+=<2_80U7Tbkdos9JOX!M}Dm}EuLYYfBWD5|NsC0|NsB@ z|NrmPQssX;6{hWFdn`Zu&hxaGPuRz}N^SRA#|>*6xOWS*yXH4C4pM_jQ$Av|J|#4? zVFQquL6``d8!@jM8GJd9Jeo6+iim}T#3W|M7Xg{Th+u*s$3mFBC=y%pK!=UL2nzX z)u_ZSxiMdMIscv}GTKn%aFEvB{G9kGqv>(%CT zAV9z-2Ej^OssLERV;K{}4G$SK$U;%4D3oYPEo=x`wTEm%!{7K|RMS~=NT^`6!vz>p zfDLsRNb-WunTU=ChjoETI3$#y$Wu|^PIdU$qtvWnE0O*RZY??z)6{WB9#?I+J@GoQ zB>pXO#JX1WzLPS^Jk#{*KMXEf+D0Q7xHQyq>yRC~(uyjbvv+YCZG8O=4tY=Z)-|nI zy^k}kytSWl!oIm$RgIeV`~BW^@wNYsyWMYH?)Uco)?Lqh|GS?5cx&$OEpJ)wwpr)A zao)e5z3#D~BOU;zq%!$X6Z+Ek{;#9;04_l&gE9~hxa6+`0Scf>;iGm$mU6-d)KE?PH}ASir90)tvh#CBIM zl}9KXTg3d_R|+c77e-CWDF6H51fUQ0`D4H9sWB?nnlSVCR?bAi4XvM8P zc>BID_Dt>?k301sDSQ7HmccLVO{g+eJG{XxW7y?sUNx%HSfsxwq_KZk{U$q^mEXd( z*~?YCXB}(qRKl-qejMdWY%$e8e?QAD<^QUfZwHHwsHTf zhd)~GU*GPvmu|6V2>NeTVbV+NOH$e(U+QUVMl`5Dm^KJHnuDMW3@{1-TMEGl#i$IK zFGD9R84(b%k%Pw|8Y!To8Zx7lS*8Vmmz{vBV$n^7MLG)Pkc+U5%N2Py7u}1Jf@CbI zs3#!+#S32)k$JT`ms35k6O7znB>8NR^*Tm7lr~i|DDE(m0}Y7LK9^3@sn`=DSezA4 z)T(>3L#m!u3qX}Nz1&*RsPWtM_q&BW)|s*NlU}f`8ySHTJeh^R3O-@i7}n(7r@rwE zd$m9N#eH{(@o{}(7O$#Sk#(wKzcF!LX4#lXB?$vmD}J;k_A#1$ihhhrGpbN8M8S|Q z`nIfa6{pB7%z!!=wdIgE5~Ugg5}v*2}0x;6x4@@ zph*C1NlhB^ecn>(rX-Ee5pxq=526fh<2g|WVtEijfi^w?_~RKIu0l!L+MUdT4})NT z8qdioh=esK;Ik(Vh0_FTFR1pMYnevcq{73KoK{yDz8b^WuB6>Pw+9>4Df3N5gG@z( zePWc|D~#s9TDI*pY#d3$%0wDS;JEo`fl}cTo`Y-=vwud!HnOWRceQl@TKR;kXmFck zM{LRh!J(8$p%eroYzPu0b$#YKI4aqUa4NZS5eWogTn_Ng4XmR%cZ^C#015yi z2{K7Yg9U<9bsQ807S>3Us>KhNDXAsnjHQW~t%y|{a3ZP%nUEYjvDr%*U5vfzA}0v} zDIuclDM+QX80s6d4A8(KX5lg|#pMgKIE^y3rxWof>FO^+c^wNz&$d^aiOY0YZaI;H zI>cw!n$&wA6GDjPKIu$O@|%MPz^!#xp4H53Ut85Fi(}Kq%(bnu+i^ijfue`592q<% zS7u6KsHr_){a_0tCF*O^nP5hFTB?mc8UV&oNYW}S+Npy;5Dx|-_Nc(IhMJ)E8q|^y z4tUuC!g7G4mZ&V5LnX2hJO}{@Oi|&&QIQ~EH8*QX-y;hEhDI0-*=Q={_)^A*kZM~d zQ9@x;EvKkkVrMLgs4~EYw~671Iz|yN6Kj$qiM(4#Kqn0{;Cc^HJviPfgW)>Bs8g#@ zNTkAzOuBr^?QG`4%R^Gad1?xVnbb!1Tr|PFl#d$hF`;|8ZPeF^tW8{Q1@&0C-fOr! z)Gb=x*xok^nAT~Ckt3;}K!`k<2OYY+rD3s4;l)*b>U zFqM)0CQzCse9Njbz=jI}LoW&Wlzu^D3K+w_4q^p-TcDtH0I#I}3>agE2^I^Mb;v-Z z3n`VCojMt+x=?g(VgOMIh9%IqYFU*>TEqbfpNej7l2t9Djz+2b zXH;~(w^uCZ{{3jo$7H;tvws;)oG|;DW7=M895KDh+oaw*%UsuR&o9RKP+{qJIYwG- zsb#5B@+}u;z0`dvQqV*RyQCTm5$&#-Y1yO!7yxMCW3XlNLP#UPOWeZ1%T978s%BUQ zieV70vsM66Msnu|fvzCH$v~%H!$>1Y&_Y0T4kC>sMv5d15V>)ez|$fnhJqCcSk?Bo z6Qr{%B*X}|Y?8_i4-z6cIKWB?cz_^=)}ZJq2xM5I3+p37bPog0DYFfMi%iCv(qB!d za+*D)2$J7QlnPT8X<(3z-a7TOScPYu-JpSF(TAPhlE`htQ1n(i0my5^^pv>L>Y59e zUWH?FZr^7nuI0OSamzav?^&Y9`DgoAzjn?%{PFu(Smm7T>kVO+yZqhE`Op9F{{R2= zf5l#uKR-Go>8n+P1^~^5IxGr1E}Jq2l7XKk%4lIDWn%)kF;E9k zX_9DyAb?O(MgUzH%Yu+K7z1uh*~&O8o207<)IU99AyrMm5agZn;NX;L$P1ERfJ*?y z#e!H9aG|8a!z++Mjxd1WD!`}%nl1WfG=#(yAuE9ZNQH)2jF5WG!E7{kauCPRn@d&Q zYba_30J6~i0E(!r=!D`*p`}u8ZAF*5@MF5)i}j}? zRPf`6jSb1GHf{d%ty*s=?9bS>jb2~Fv)E_cV>nG}&RpGGvB&Y=I9tnCCKr8$)Oe_S zbUSobl{nMC&Ha^7reFX6G^h}sVkPDWPJC(w)d38MNWnp9-eYPaMJoWwhd{~_X9CKW zv|9r>f>IDrB4BB!s>e{Npfm_Wrhg-jl@|fDD4Dbvh|q?>LXdzZa;FM_N^k%I{iI1} zkRL#_N)2Za3QDfY87RgHLIDhrgobG}2_UJOk$)S4NG*0&4qITlrZ5CtXl%wp{$i0W zfmnq`pD|{7;Z%C1@rgY=PFDn0q{53A|0t9@OCNz8YDsK2Y6*_mwS;EfJj@eXo{E}^ zDSvjWW!X%syry4CQ$6REZR-sGd)Ika@YnzQ;so!H_$^t^gL%Vp@asA7Z#ZrrU1>ZO zy#NFBGG~IdkN`5fjx1_6MBf{qw41==AHmU6h`oL%Oo2>>Aw4gk04L}v^LAV?%R7XZox9ws3O(NneF zn@rhq0U7E}uGS*ETt$$pxXWH9vZ|^YUWFH^!czgQq$0Pv${@w0Qpb*aDW~#%!??BL z&ZG|vMIutXq3Kk*DTBQim&tOQ7}$yLiNGW0p3m*0sEIug%YD-t7I$ zSHF7y{IkETJ97fU!%#jvOADT>SE{!;Ml1=7qIFV+R5oD_Sx^Y#Cg9=f(qtEfPLmk~ zfkwn596lBbG_VMxsZ#*tv`&!$MN^q+wpdhR%Ltn_H!wj+fMh6`nh_;4TBQO&z+(Yd zDWNbyK?4FV&=eBQ1_ZGJ_w>U?|mD z&OMyu?v4!j6vP%R!I?8^%(-J*1i+Fp%}nGoB6!cR3bzW|HQ|m*F&Q%yG%-OSqpr*d zL_$c<0y4*pV8V^ZePXUc^r#^WUeLgx0VaH##Jxr9696*gjIfn>Of>)~19FD~3l1^@ zfJX~HEkF#M$`u--C@rU$F{#KPFH{sENit;vap9u`7<70vxFlj)GxTnAK_m>QwnD(u z(8B_E-hD9$ZL+0&BO#&f@IZp?haoQzjMDf*fG|fDD-0-R^+n_5)Q)mPBCP;en7x%J z7<&s=%Ls1J5TYu{2!o|!y>`pmEIpkJ2d8a90l6T6cI!$kVYyzr+jT5aX08?ic0jGk z2Mbt|ZUske=WKB8<{DddmY)-EsydgEwr=W_vLSfvay{7*Ynu-p@BlHPgqaf<~s(mhyHR2n~ph<4IE0$E>itiSOMDit%J092qb5YpJGfB*m*AUPrb`{D%ffDE6IPzG;60e^A|K+R|X z96h^M9h?9IEVb)bua3&?850_dzje2NnuH;{uk{s`6@g0dXk=YXvS2CfNI9*tL>x#Ydu(VYZZuie zhv(_#nBUhFe7=%63hV&4;)}|TI>=cn!5Bb~`$$aH-(k8u_)99!(cG~Q<%CjhUpaPH z0jPT#u+!yga9a1)Ue0EpwD(i>P@J@o2qFP0Yb`lbIm%kT8CpwQ?zznKm+SvO&tIOo z%>TOQ|G3WtwjY3RzKptNFFTz`mp?02X6i-d7-OBx8lsrA2=hyZ<4}Av58s9&dC9pM zw{JhKtSZt=DdVc-Iy0bv0g580DFCAE>L%AmMNowoi@lG`{A=0-F0?=jnkYqEk4IG- zt$s4QY`f8y>le_7tTocLxi=+`y?Bd_a(&r+o;akgn>#Y-#VrNAcOS;YS_PlVOD)2* z*6l!)(S1<;TUBaErI+Y3vy~OBDX-S;tG2T4HRkPoOsiI_k7YNvmaj_t8<^I2E70>A z9ZB(~vtBojcWL{%cQDGEJJoL5sh%@W{T2H7NaiQ*-R$Kp+1nKMYT3K3UdG)nb+!G^ zm|?H`*0Z(EVRE+32}ehoU`%6Q8cVlpIWNe-00KIsK}Qz}iHo6wy|5gK_=nP79!+XE zc2C=#y;ia-fG1-u$~7iYKpM8Jz*R1eR2(O5z?ExWnVYbx6^p1^nhK{%HA~6ro=41$ zhYwVTinv0Jdq!GGM`W{ech$8PXbf4qg=C3qMy~U!ylT7;JtT`*bc?ON#`m3H6w_no z`{NIB~ZFp^w+;v7sF(tFv<3OJBPi3!ZFzzh+du-O0 z`+FD9SuijT7AzTX!z+{*FuU1*|N0e`2%0fTAKdB`djOyVOo)PMlB#r-RjQ>3S&20a zzLHlOO$RivB~_}G$!_qM>1a@|NK8Ses;h9dA5LQL<5si5jAB^=Iu8xFj&Xj$m`&j; zkjz731o|~X;$h$z9watA(UlM^m?VNG8_FMaiPzCQnSmYPzXYEOraJv4HI zM$tTi)D_y3Z(^C18WXBSx`<{~q|OGFFv3OHw1`d@q}Ev*l|b5(B}O)l3^q*`rP9lc zBF~z&DbKhB1wa%;Rfkf&u@dB-Wfk0sp%TzB+cAXNZKC69f(NBTp!T4%l(FS?RwRy7 z3U%7;)%FT1c{(W;*w`d!>cyKkMD0kBibWfXy1~QmA9is?|NG(uh>!M!X;gzaOK{=t zI*?}xZW^_-P7L9V!&bKH0jx2&g)9L_Lwh<&6SZO*fM8fA8m4!^B6t!^j9d~b*fJ** zqAS@%SbY{6K`c}~HPlg2IhIh%kg}k77eslBqyuBN3Z*%wq69_=+hxK5b{bS+Gn}Dh zmIvlz1(;p82ZjX;km}Y>cpWf9!PABI1n5*?x)Y?KYIeCCV9FJmDp=+sX%fg9jjZT- zWH07;$*sDRmn6D^s|5*4h@i`vcef&XbrHb6fXEFkNWTQCzzf!bkNF6$d(ziSGcTq^ zs%NTJyk(9Xpqs(Yk;4kho8*{JBU)V&s1hE5WiiF9Cu(>he8wprhGyHi(s=uEj>{dG z+@=_wfgNe5aD9b==zukqP8b|SK@gL5%}}tYhes()YV}xJFfnG!Q9Q#wbnVa`OJ;qj zH6y9z)wQDDamTAHK7?0W0;V>xIC^+>cJa8}dzV+Bso^~LwNm9UFiv7Pu*rSV!1K>D ztDkye%R>e2@x0r7>$G|)@;9*_H`GPjArMz1U9sY|Enk{v0#~#My&skj) z{R}*Is!+{JC6ZZfG@3BELSd}$D)EB>A{EFhQnFz~s)2*-WdRv5(xPd` zEWq($KqJ7N7D!v?&84-KJC$OA>Pes}^%_}mCZL~4lLOvsW$9h5x-Udt1o@Y>uzC^! z_+1j14ko3`xrRThu5uvlJd-nVb(HQ)o@YRko@Qy5{NOm`7l}hi(?&S2D-@~pvTaz% zo7ZIy1FN&uvn6Wh*bkq%INbuoj;~JYA)$vP3u4x909iZtZ3ju|b<=s{(9t|Ac zsLp8C9WsfQA_gepOG2W&0wJ5oVR}1GJf$I!iS3dCOonOP(;j%@c?Z4vW~$z##9(%j zvWc{F0q|%pQ>gVfd&?P2nZ&YD06Wc64r#c=o~F3}zRjR=07SDiGPsl#3r=nW#DXBG zbPrb!MgM!u8ztFg6(*vE=SHh^`jve$WAjTycOB^q^@}l{tbIpnx1F@S^Iul0S6N+c zzFIWYq`iG>9>kb;YfAdNNZw{(tCX*Nd;eE#+)vg#pZR1F4Ff{11poWu1kw-o&1O>r zSbK2N?AmZ=3~nENn??=c?aS}CXu+(#xB`Mksq7osPL`4~?qZAPEkbWbBGIN8Dl}{% zg$@uf07fhY0TL((L1!pVWU8)Ni5Q1UO|?-IjuZsFs!eUV=>-*txI#rsB?eLe!K=Wy z5ja&a*?U*YP}+ounwbnjtN8zX*=fPK03K2XLGVX)O&U2|Ni% zIly`ZnCUHpWLQfR@Z~esR|ngA!vVxzQLk8%QI$%#F5A;FSvIC)U2P7B>izxURukyR zTon7wLUC8msPjt^w-%l9)64kJ+oQpOED7LAXgkCiBf5aqh6wRqHN}Su5Ob>I$qFrW z_5>}sz^3M&&}v2t&E@u)#@2YQv2S;~|8U6-(@gvoJpW4@3|09FOdDh*)cEK>Ny zBU43DL`QJCZV2hgRLEL@Jfvq91iMJSJjg-k0!Z`~5JDMs(5QHoHB7*9Kv9e`YyyEw zMUJ}@YBH)&S$&)#5NXK4mfN&nR#;m0O4mz{*w;i96@Y9OK^+$nj;SF4EQJj;6flsC zMCjBR$isw}oGl5nn7Jp5(gzSBJ9CVEsZ{7RHH{G3l2Ad91y;CjolBcIO^d&Hy4_jq zouc~l%d*Wg_zzqovqG9`;kgq?I$GVL$JE!RY)#MiO5+9u;u1A+JF_A1L#$PG73Q&5%9|mNPd&S za8WBzvU&rv5Xta^MuTsM+q`E3lcz4FSPg^;ly&eTh#(>CHA3lB9By)yy? zD`GpF1IMx3Bin13kzc)mI?Q-(Q8$+<=Tx;{EU=%mGRpH6%+RpKozA;(-J;q3VNH0O zwf(cLLDhBle|pxJyt%jkI^OkbYJHJ+>O>Y`L#7J!Y6VBuVqwIF20&v#CJ;u5E5HO^ zVS^$@MrLJD479PyA{@Xp0E>dHh;bAwh=4F6h!@r8E;uw2?=DnXkFI3Ky51bhcAwt0^=LRThxk*CVw73PcpbbnOQV^z^x(pKP5RDZSE#C~3 zMR>tX0r-7r*GdVS1su6R-)k;~ND1ADNMV;5{GP^D4m@sTDg&Kf@CB$_Jc&-mCTvG2 zYH}%Bw9PNt+~q8`-T7zZ6`=WKmfgJat8&HK+nJcke$A>%9ZuQ9Em+kA^;!S>;sp2) z_+4{Q1DShq1MHd*Z#ZsXNwY!?>kY&2wrGL9VYp1~P43MtjOVh$DVtpGwcIaU=hj$= zCvq*v^-omV9o5WY&qj7|bgHMSjAbRoVZ_8HqLQnDC~D*Yf{(>PXMA{xc%UNwEeLso zS6?PBNvH-SEJ7(I66nE*H3C@bHyEI8El83M0Rb8w7{Q0OWsWRKcdH;23Mq~PR85Eo z4IP~2j2H>C7j2}xX{6IqwYa>ru32eSkXtP-A6?4n2U7(ui_)hKgBrO-2e=5HzamXK z>^!&Hf_1~LRIVF`V2DL5V)J&BN+8MhTKvi%n7_;I$)R-A@~PSAwU~OIYI~4H4coT2 zNly;phB;Q}X(fMW3R&LsJJ$7$YgcW4RM}h49oEkrFroe7mi7DZKVOf3K5zToYxV#C zzy03(6M6Qbl^8McF*%iu92+r!oPmQLFaY9}2+ETU5d?sYFby$Syera?7X(N+IDp7qzXyW--4S`KS6BzshVrYHs&uXLp^NS#NCf zovksR@RM?vFUrkpH)%1sol5%pnSNTWe;)H$b6DfA*7L`_=B)lWXaCRN|9}7Oe40KSEhDj`H8m8ztrf6I;0+pyZ041C>2+%6Pjsi=V z2o;iE8`XWq_fwfv<*|`YgE;yH)DM;W|ql zC7Fv_j?5O#mVay{|k9%yV*)?;cF1$&k>H50*Wnx4zY>W1bhK0jimES z)UIKVI0m)~hHF5+flv-0;bH)UMx7)AKP<7vew}nUt?)=_BTbSJ*+FRoh!i+Pst^Pa z2o)Jr!7+&iBrV!V!>AUx?k76iQ6(ExX>guQ4VpabaKB=KC{h(Fch$Pd+~s5*De>T; zEI%vqnky+yqucM%_rQ4Q0F58JC+qq?tds1Wh)b@6Y8XcoQEx) zHLxmJ;6;fOREWhMcE|Q-iu!lAWQ8lpuVuEPJH%bvSA8Y$@)P}Pl2bIq_w|*IlV{Wa z`{D%Yj`!$V&;xnHaQF<0AZssfVAY#ME$0o(<2dNStUb9}&%O0a$Ho0J@>nH9$9LM< z_!}25-Fvi&Y$JN(H88s z1fFEmEJ`a4!BHDfbYcB1tbkU+HXXa~RLj)uFXZhOGSl zbC~l!Q&VGSwAj?&d;QCM?y#-f9JSmzQuV!8%H?YldDO>PSl$1*D6uzclbC)Vo!k2i z2qN8`CsIidGWbn`I1b&u+!6NEvVq2VpyVS76wv`eV5nnYWdbY#`9$O<7ywL_DHWwz zT|l5qB#G(lt#pF-EU=bEj5r}?r4qx8g?OyEG8Fs+nBNNBTV3MpCGvPLaRAam0g+@$ z84BkeVrIUn#)Al=Tlr$_g{5!+(h4t;C+L5S6PTeaDhd_9EE8rF z>*JLVSWzEEg>59pt5HF7fQV!;_N_=mdkSa~*|%pFN!#Va{Y@lo-W}=njmL$5y=!^C z>x<*=uq%Dy+562Q;?%49-W8^sTfEqav2(1U<95dBKmtw02Ln)dB0Jl{t{U76u`M? z++9$4kv(g%GV-Jo_*vv}SMPChU6$@B1jr~_3LrHZR4q%?gKs0N8j&WNdN*~JsS2TA z64f$b3f!y+w( z-%)A%_=bd6$tMM^K((V?TME>3jc5>a8oFopkxyAES!p~Scv-#o7cj4TTW~R5X7CJw?f1Oz>wCTHdir_qxplnHcohgnq=HS+fortP z5*8aVFv3xg7_o_kEMZ{-D?V3i1g4@8w^$Sot*f|cbyomFgNm^hS`wYI@jk_;L4s&1 zWtg3*$QN1#w(T(<7F2}hHwv<7u_s|QVyf|2(^-18w8~C*7#u6V(}lX^OSv+I;d-o9FqFWtDR>9UTZ+evCty z9i6O4%7w||wY}tM)^m?|klA3qWP>f46zrSa(eZrW8>{P6b%}lbcr=UipG`-;wfuOD zH?{L0|NG(u=a2W*cF}`)dvg0u$}n#aZXY@4Mh#)@%gDND!K^*F{8k^Dl*}Abn9gyl z=UyH@Gi>8OSn>6Ld}ny3E9Vm_C#1v0mLk;Bj35(Q6x9YFt_2zpabBC^L4XhpG;t@C z^5cNh>RzT1wBWF^~)X$fI*iK^7G>3V;O)VG1tO8Uw=M zK~HO8QV6osowc;zu7to$mh8mi!~qkO@^F`)nmflilrDrd%#X2qJQWALbFq}|d4tWl zMsKvCk=6R0Uan546>pV^M-!cqTEo544PG@X93xG33bw|9Ti!|HJ%=AMJlB#0N?$wn z)IXi?z@Hj{h*iGig@_QhjbB@m4nC^(%}(#ASdEt$Rjh5|k^Zj}cGh+GjQAVH^Ap|< z?KU^7)|<@GLX4E3bvB*viSJ(OzuWP z<6Y}rZY+dSX2EeFdS9zCC{Fz0(=Ru^yGa zD@|KEi!Lv^NiDtpAwsnv!N#*+@%Q&zZc6UC-m!mc>)+N{KYYf>CuK3n;)+J#$78nHAX-6xak}Ba{jqGIxkU03}#Z zuo@HAs8lG}?U5>BJp`VTZn^@J5o$Q(3U5>KRF$?S+cW8yB3^^wp}Z^kN&zls@`<83 zV5=7+{cKv81=tfJ)2Hy%ateD2_i@CzSBj5Lxwk;Oc_pB@96|SP<+Qso67q+W>>o(lltSrlz zIK49x6>AoMx3kMGpynsED%U&qtiGOnPrS)cc|t(MiCtsF-G}S{`z{b5pTJ?LkeMNP z)tC@)X&A+trSIVog3KsGZBWoED#mhCJsHGODx}yYBLowOlKqct5HQgR$VCWqB1MBj z83nB?2{UL?I;#kbT-U;q2!1n&>`&vVg(czbgLEBXL$FK%FA!$J+?4a4KDr~$lTxDj)|{w^vx3TvXZJSA{0m+W-IjfWZStL}X`!#`F$ifeCn)W>iXwB!R1>5Dqjj zfHdrBDI)==I(?`z#bKth8BPxJ@lRmErI1l&3>+dth5=OyBn-$oKxmlI$CLM0(tC{}f<>SKGDJ&Lg-o#M z4VYj~`*y5~%2L*!+4NOoO*RB~<+AtEPc4c~I&b5r47BTwLHdKGPRsrAM{XfKTE;dh zWzq^8QfV$zQ_>1}+){${zLHl>Aiq1v{T8yl+Wq|OTFQ2dwfI}59XcLeGrv|kd3W~9$B%&zD7}FRdC_^0guuxEPv%!TYaMNVSw-teB zsUcadGNq1$(#`{eOSLUQ3x4c5$t1~z@#Z(;U{QUg;fB*l}|NsC0 zXg3oq8apIl=%!+1U?#@aIwKfPb0SwTfB^`IaVdFISY$Oi5b`$ATZwzmT`fC82Bi>? zPDn-40|3fIUTY^5sCoelCM+Qm%vd%_I@Q5*()K`Q10W4BVo-TaP#Ro95E;r8B8Y=Z zl>k$qdP2Xhit$jO-9JHQ8epplAhrfbS&ZQj0x^Ps0!?bq=S5ut&oDaybZ% zNC62qmZng^BPS`oobQgPew?=V1Q<#6;4MDWcQ0x zQmrf*jQ=lfeMQ}+fm;9j-~{Ur_uX?(gL!*$_bhqvZx3!D!H+%_ynqA$xu^oQfC2d{ ziK$KHs<*4?xc?aW&c1*DG0PPFtV~Y{s30+R0RfI3l)%@`T$sc_5wu8X#O_QWFvW$Q zqCz2|)H$;BJWeKbrQpCoAQnjkv6Hx=?bB2VL!?@jehQ$9z~qzM;(!b&$iV=L5)DY0 zVphV1IuQ{fQaoAm>>9r86QqurG8s zL6j$p2JH}#fYGDJhNO0ipsrNJ^yCgDq`gk+{8(s1@WWpQzVQ~l*UDJ?5kx6b3tUY2;OB1nH2d0N=&qU*vBC*T#dCXnA->0RVrk}fGxn0K_G?`ti za^K_4_SU(T5C7%9|NsB@fA=s@15Z6e5eW@-RTn`&m2!eN7xmSHTiwC)@m6Hp#GVMN|Acy^z6^+5dl(&gOd?_<5XMnn zrC17f-)+jOK-KMAl}hQYMd_!l)7FP*sk6>+S3Z{I+%map;M1z`qr}l{{Qd)|NsB>|Ns5p|L>MMsx==BVKZisB-xH)XdW1WgIff8gh)=xz;ZBX zGRp#w0gC}qh6G+?$6%lW<{08>t&anXj2KwPLWn}lNN6rXYKUe$5OsjW!$@GD;NTE3 zxWFP#2tZ7PXw3&q7%VOwF98OnV&qJ$2SE#b7#3Uu2m?d(=|Gu+5v(9MSWqENh=SN5 z5Q6j`01*VN6f8I-h!_Y)_K1Q}{75ihI3P(j)CrfmZGD-kglWca6a>G7M@2v;Ok3vN z(^B^eT>8;7w?+JUAxdDwCGux_B-&nAOC6E6@9erLx8I9U8|gbu49YE7=XFh5RrRpB zV;b?;^rkg>q|`q_AH93J%XaT&k9*Byyk(O#_BVcW4p`@Jck9M!Bslh;s|W&{eS=e|NsC0|NrNndc#>`zx@08_wE1Zujl>x`mHLX$8^};%PU>AW@>)bs+8H? zt573>&m=tT#48a?1xO3113no%4y<bp_ygcOH;beU0RBz z23TW->#+1nH#1(I43EPRSw(tUwlSup=0D%VK4(pTvm47C|C{c4-_?!smZaXZl+MQ| zYIpVj`rLm#fB*mg|NsC0|NnQaKUi;=e{jPLKMXmCKmY4f)ZI$^);2dmc2(M3w`F2N zp@29D#Rl{$xGK{`GDVKk1NKKXDjGGXpdqQJ!Xl0=lt{e5LDnz&pbo0h2h|@#$3_6>MdNnO!zB zcOr8YGOJBqrE7b_mssJRKfL#j8R3ubd3P%rW4!Upo$vF%to6=gth45P-!t89_qTP8 z?D>CRyfdj)!I2pvjnuYkYs8J&r}O{-9Hdn+u0>SLp_7F zfCLl)NCg{iWHhyzp@>+hYjti2hYEmLltPp#5R$bC03g)GN7NM+SaZz5l5B`5E!Jx2 z%DbHic}g0CKZDxCCQv2kFMnoTs15{TPjlwl!(QdnLoB`uaro-H@|NjU>Vm1}qxr~T z*b=OcJwG`?M|Ql`iaN8lcS%1tdwI{-ob66iRqaWc%k;IXU*_}PRq*-!{`Ho>cQe=b zyVn1j!@u`3)*a8gvzGG5J>RdES8&xGue*j;x!aeNWCY+{YrT6lPxCEq-}FE00DP$k zfPm)^mQz5;z{5?+(O@v*U|S0ta+tV~fl*_?n7AbmOT~k0ic+t@1TEZjwS}lmI20__ z`8Zg*hoSmmvvjYPCtI4JaoP7Rbt067gv*vwa!z<{pDBY6vfUS~7|{nfbRWd;xGN9;Iq2P`;ghqi0}8A?+)uu%9_95^tbZb!Be0*&@~><@`%swo9~YXA)~=rWK9RNoN|0j`+kDw&HQkwx4C7G#9BkRAn@RK&6fSiWX5U?ohOfKoD& zBvd#cvZ=`IS|q0i0#qIvM}p6m2N8-)Ieo~9X-#oUk>* zyXn%|6czxIj4<$q5`ySXOgCkb+&l;W`{D$tfcCgvQj0iybmFUOL1!;+8zD7DEoJM& zjjia#ti8C|!dM}i4M));FRknqf{8fU5s|32ic~#gM5j_atYxK`FBM6sitNg&XKII- zO{zw`NpHUreMxDj+zdRVcyezw-oC%i>w4oE)vHW+KQFDUL)N1S77YgqyacBXdM(#Q zb)7qBzfc1f6ee&cjGr_Djcit=Xv7&83mKpx0%|ANuxZL)uyeqcop1>x6}$w8lv+4C zV#N$Yi~2MJkindB>Wl)=fr2O#O)kR(c+<#ec8nZUAxmU!#zxeUy;Z^TO@U-jz$77p z#5&RM4no5O(>%6KfK|!{+E#b-TaL?*dle3eh8OZDwtPFxeqSq%K4i7AnC} zVonMPpPZdxGo@*7a=%;r2`+4?nK1yPXK+bp!7B_xF(D=_n{nRHj6%E`o82FP5IBunKYQ)PCx97PN+ znq^1Jl#i*nTO`H?2*=#vV&Eu#9?aKRVIM}C=`cM3dQq8yk`)is<-t6V3^H~&i?M8T zIOlGTTh7!WN}yIEoD_=`Z%s4C-Ce{@F|%n<@ts(jaGM#`B1g0byLp(BNbhicpwkoL zYU-4(KCkzvU+&euFZ1`fnZ{?jL5G__N$fm!o<;UPB9VGQfsO$pq66$i;=nK?$&`Uw zkpl+>M#7>48ZgWa7z7?sDd(C7m;ixI6c}lnk#|hzKun4hU}hpoM2?_GPci{BQbMxy z3J`24%bI)woQ3rm5ksE!=Q<=X=?V5(MnafPi8sK?qsRmX3Y6v2Os6d?glI9r0Sm0K zWf{%-S-}NHG(A;zB;yekFIPg9E9co{x$5zqxT;1z=|rKGF<>kT8^Q!@cPJ$;Ou9oD zbforVGj(OOGRV8pJ3VWb?A5U?-Pv||Rj+ziUM2s$bG7yNk9(gm{o$T`!v3yzz0X?9 z4dMT~-N*Ug-~a2o|L@s6M(;OO2|yAH8Xz}du;jB93iCsh^9DMWgHN2){KMD0&1w5fpP04Q3z=!C{yYP5_>OD6ac}SWNFfd%Pd6p zXk27TSX78cCCYk5j1}LUbhO)*GqL2zE!m zmqlC-A;w!vDXEs&vQ8Vi9EYKTyFo#cfr|tscdEI6nVp8Xf_X(ol|u8gwsP&Y2o=Pi zjylXfy)jEC)HnLBMku3o-^& znE(b91H+&qqa_JLA?OByD~WU%1q&FK!pZ~0GnNv>4IncC0A%%;r9aIR*{ZNzF&CeW1dvLsV~SCS~hPvoyR<&x7m5H$2|tIHvZ!;rdo z9_Cck(MetE)pY(taobj|SF1gC%s(%TO7V8dcG<0^nLCBwi|H&Nqd5isy@GdX~xB>|EHnFvXAh5(RQ zFx@-0?JDRON?k~qYjz<}#koRr0K ziqwauWpWvZ`X?ryuV#l)`O8(Ul|^`t7H27 z|GVBg{rFj2D94;O|6i4&MuF?G|y zh8c2#(gbA@%s>$a%^`CDj1b7k3ju-+8f8P7Vn%EnC@`6U0HrBc2Z)9R#5@Shi2wp6 zKqz9D;xOromvGB2S7o6w0TzjSiH3qowS=pAQm`luv%1OzuFNnufI<#dtt(y4UBW`v z6(ZO>a9T@&8d};z2*R=^lSH~;cMdGuy7CCbE;`vG&!kg1d=DLWqZ3c0jyVRwdw8KQ z&1dE*Dt~2km9NBP8DF<9rgUM=LsNanwO`rJ%Xul*H2?eJ1o40f3uDiPZy*5(Olk0~ z=m0BeZGS(gE2Z3pvB2<)fMVpAi4aY4w0?~>HX9kLvF$zo|^B!=^AOZ+9p#&RD zfkSjOL~KeJl6QziY$|LN2t*WhIWS-VpgG6IZwAZaraEM((7F0l|JHg$fMVFaca065u*0%H&k0tOrh7!p8}NPHw6 zG>Q)w86XrvyS9=wf@CnmzB(Dce9PGfAW2o2BjnCdc>(do^))GA&h82a7ltL#sY{~+ z$rkepaNOLperwjNFNGw zmM`P`#_u!lcb_|+Qp$VU|Nj5~|NsC0;jQhC4bNz$}I* z3UC>e7Ge^Cnn-3t6qrzk1~?ehKxB|Ho|*t@S|P#mgl17GvL+k`KU<-z6u#ihvvz@t4nml7b6NFx(s< zJP;NKKw$u5b`$^_7XpH^*EMUK;o#m=QIc!SYg(?60;sk~O2D)2P4{HDh z-7Jbh?ce~L>5oJ$VeP|$EvSX8J-HB(WkIMy!ysrh0uZ62JZ^~eZ!>z}mH_O)D5CN( zG33Rns;Zf&k$c@Y@mifV+T~kV7j}fW%icorx=g9AvPUX3-C-$Hna<8t}gL{7zf&$YXA+`UrWihOsMFHmJmt61)O-P>FJXIFa1 z4*og*AHM%Nmi3l7WBK8i?=9Tj{BB*>^ZC7hKfL|k^rZj{us}&bOp2l}=VZBh9#Co% zNLWKG!5T5-0Z;;o8yjFk;wiAD&?1OLfL=8?VJ&%W7kDd>b<@0wMX)nv0*lzR%cyb+ zH>V0f{HRih4M>qC;;jHq$cg-oV#@t)belS#(NF^J zvJ!G97FpF2XIKaX3p5!$E>mTyL`=P4l7Q(y%KWmfTQW`1dC(q*p{W9q6&OLCD=bon z-G>kw7VO;tKwXQGXsD{gtMvX;Hw9_56>k<>p#4iyNlAwuan_5WEmYd#%UG#=xQnQi zC*hn-Q>VKl7(|Er!;qhyAzBz^$qX9GqWGUK^C}@VC!11B5!ssOP&i>srjD0uT(l&Y zERSgP@^WRFy?P!XK8p(auBEH?Yj{}2GZ`$M1zQu0--Wj^V2ptyrD5dg(TIp+gfyd5 zq#L9K5v993rMr>tZjhE#y1_t1QQ+nIU+$o6n84w_gOhUmCu9^Xa6o zIB%O1Cab({9yz+=<k?kw3(Xt^kdPkUlE@@g{wwZ z=-;HZ|40LJ0q?$GM@?iV-HC|%)A6-umXN-*hj2P?@%lDz+UyCQz9(NoFpyZff*7~A zIj5rkb7=7=AD4ddFKR11A@74Ju;;)DiIk?8Sg5N+wb=U0a7{_yE8?i)uI=lJVBo3ihi9u z6^Lw1@mbLyX!866;hK`4t29F7fWT{Pgf_shN zg@X>e?bUeKT||_!l0m^D34M8I=Cs^x)E1gj$>+psqRw1%RY$Cbv4rj&RV*aVgbn|R z!r+5nUkzvOpARng+avt`BS~AXj3II$9B{9;mA+pec3z1)&6w65vr@7*fgj}`@Wv`F z^TcYe+bSJ?x2kfQQ?FF^`~2y$wsdJbD9@Z-EoHX)?oLa;BG;^+-S6l)+7bliOrQpY z{18QiGny#x$nwl4hQ-6#(Bsj>QX%q^ebQ7jR4bu@lHu4fA5FBWgh`C8w*6)}0lHBl z;~U(U*k>3L5QL;Pl=r$F|EA3&mxz8~_?o{A_**x?R7r~=C$3&s9K_Y%qb~R_V8#5@ zaW)Z~M$|gYhD}?NpUlQnS>ep_8iL6=sfc7wJvj>8YVH#=!L@QNZHQ&zo}jUxJ^A#$ zZ0(G%$G3$Y)h6^*^NjuWxxfpePkBvjMI&5q9_2c`yt}M&Ts)4f>clJi^p>jft{{~T zNo<2EKn00%;69Cv&qxObk#!_1djojr9EIN|HXF=&M8I1jm_eY*$?tvJ@y!4pG(j-- z$0ksvaMB|2$bf8-z&$EIq17DDT`%T2Vx=rX#{%h{WEfu5}jJ%h?WHtH!=uderdbQ?bT+;zQu zeDIWS{l$-kcgOHS`y5bqruo=fEXSkrG~5xuvl1IM3m_f{4~r2*Qf)p#@r;@JOXta| zd=CVfY=uM9pAUpuXy-xwK|!?4Wz&F3Hn7Y;ZhLzF$r!`9F^B>R4>kPxdqBY8!#)t( zFXfggz|a9Kz)X{k6Om|VfUy%KovdgTPZ33+xx;lK%$^OFQMP;%a;&?O1KRYecnC;1DJP;1D%qdxvT60z3-W*R2A|_20edlo(qcvs*>ynL5Bdv9G zpSucX!i2ZwT8S#j)?zI6iU+eC&HW(u*3w#nxRR;B76gS8+$wO$Js5&qV|Ow6|j_S4+#;* zz(B!=W~`JH4CH?L)CiRFLUS>Sj2B(9BnJ=<-NUIZ*)2)6M(Ee477bEQ{9LEeOnALw z8M5XGmovzCgCoW}O%$ivonkIVzq};)d$6#9Q>aBuovL29cFJtMc2OYsfQ!}^xiPwR5-stuq&ZWthv7M$%B_BYZbRGM$4E{+R z_W?~Nz*6gbFa%HHfqz)26mD$Biv(|ze$46bn5aEfzXgs9tp(r|5|`58#XHn3a0ASHyy*s`!~F(9wR_ADHJi# zk((McvzsP!(YzZm^04M}a8vczPUSy{x3ikHiDZ~vUbk>Kl?@}%fC2gL4S?9zi}sYb z?H2J@hU;pSOM5QnEfoc29V&lNW{0lxJ=% zq!A9@a#FDfA(P9;;$ftj*r+k}JQC-?AI*9oX$pOtkF*@5L%wV~3%LT~kK5=V@w~pn^`SR_`==RDpKsvr`q>2kUMJxcC4uU@{ zB#t0bVZ(6jOa69|UP26FDx#M)?clfhW#qA`kwD zQ#gsc+BN+6pUe4YrQJ7&dz=CyPVye`K5$%Z)7SZ=wfa5fu}!sE=N)bC>yjabjy(6F zcP|<6h)Bp}gP96J6)H1+;wafFtR*@jR%SohC<=}l+yMc==u0UOUj^v`n93a7w*^Q5 z0w1ta$bJ%U!9%Irr2=^U0Ymb0>r7x~d@vq?Wm6#HJ%Fh%I$IjKEnVqSe@c<_1uuiz z0D+x^<7FuPRE0)!5xh~Z%ajR}kmlAR6(G_kY-deK`kAh*;MxtU(|EY3A*M+#jeH*E zGdnnVCY8)g5@I(1KXEliWh&wLpVL__Eb(!PRM*jKHGinsH>+`9Cq9W z>%P7zd0Q|mm9UgmnVko@4BzS=KRlmnAUdMDpj|Rem}y^{`lF~_-Au2njHyhdEsu^f zJ;aOjOb&*}M}vMCkywR*Ooux|httO*FKhNig9xf(&JML@(0soS=QDtO3eEa%Tzo$o8vQLi5M082C#eO01KuWvjJF5(Az3~eKVB6 z4t@Y328V!%1fYlwI=+!pOr4Vn9U~yNbaTyz2RNF_TM6qCKw~CseeIJyCM4^u3YHSu zGLQ}Fafm`r_s8#asX26>xA%&ea#Xczcm+?u!NmkL<5bMITwzC|yrbw&5q$98qkm59 zV-c}FWd+D6>SgaPEY}0(&&?iA+pFV0;!oaehV|O|k5Kq&2P@U8J=UaVr{2v|;+s7e zY2@7M4xx;EgR*}8lAm$dmw)Jt_sRVurBX5H%j3dJ%Z@@zd2#hE*~vGWEq{uoI-!E9 zzPuFh2_uN&{0$!(XG_1}I|<6!rnIM52x@#yNONSkuMF)U z7MmQxq=FLME=Fs$bz&kKxEh$xJ>3H86N@JgoU#19D!D<8+pBUPES9`T1EGN_|9O|b z#~%E(nkCftb(eCfV7`w&Sg%}R9W96^t2&NVqs`h#CC0ufkMuoeJ5Xjb*XF(wviEU>*rXJ&bx_p#&?EiUrZQv@b3%Xe0}<(@bhKmTJ=PBeJJ%E zpVhi=^?L0cBW}}6*n^9s315;tP-~fsp7LUnNXTd zD?E)uAL8EQP^!xte)Br2SC-2@GK&&^<@(WeM%V9e+!!NNpZfmm($C)owIMH>|v}f{z+Y*&Eg&l;K0-E+{TwkV9N#9-lV%7_Vh>< z*#&1+jV=vWIbO|eA@gIzp1y^**-Kh4)W~Hhl`@CmIrWzT$>Y5opC7#8RGF-_FFLwz z6LG5F{w-YvSd0pqeBTK+Q3xz+Zww<5_&({M=0lhGjmzmz;Qr>&3G&%K@*bC(T{=n* z2;nO;a}Z!}K?b+;%xkT3$TY zOfe4w=UY+cy#8X#F(8Q_>uVX`jfhL&7r<36T07)b=B>7IDr_?Wd-4`+TCw41Huls-C&{Jnbp<*l(1Gs#?j6{uTJ`P%w0aRHAxJ77hz41Sz+s~;aWKJRkj z&u8QI-}aCZ`rFP=`(6{=KEJG}Gdp#rBdW$$nZ-<)iB?Ewv$clrX_jl)MEFm;4TolE zmQiNMNj`CXYQYB|2&tjvU3kWNA~5fyv>o@*|){rg*7bhk6Q>E##ai^$oZ1 ziw@xP=Mc+e4rp^eC(uYK%kWl)#NMK9XRQ+t|85bkY8&h2l6Yrn_38+T}M z`!_@+uwPe4Z7dSlx=G8{-Lm`?R?nanQ^H8!7iu!n)jqB;|6ARhFQk$j8hm18vc!n# zu#2w#fNeNtf9{;)*FIZxXspr0YhJNf{OXU9Tuaa09~Vn4tSdyZW+E8D?u&#wQqlg> z!8InApRdAfjy77#r;}cmHeCe^8VEa3N_;wcewcjp}!dj!+%h8lfQelc)J1>vtT&!jEMCYGa=au9pDs1gdNG>yTHjCnx~ z2#7v~TMmr#eOT6~yd&YIOigOg-Un_sZu{XMnx*#*XBwG!yphdGWXRkG@3bOJ2N)6viW7#m^PA%mKs8BEDNal*($-+51k5=$_jl*@PonEuH_D#FB zIeB_1pXB-l(SM@Q^Wci`r5295uiM(Wy^GbUGfhgC(tn7RS54*8RrPH(yqGyH%}q+3 z2Tx12l-_68@HY|6?bTbHm3gsxucbXUQgi<3p3tFh`s(aL*+O@6e}A#5S^z9B>(9}Z zLAq+_CR$!c2xtlgu;E64Sxjf&;KD4if_Fe8mBTZMj9ztdF>JdCe*&)uX{@Y6ZDhHq zSi#Td9X*jApAPcGyMB$|H4}tpBuzaKD)|a`uX##Bpk;s8JM(dX%qe_A8X7+>d}2TGrdHWJNH$^ zv+Se^S6+FPp9!3dGvoh04rMI0N}6mpN1GaF}`L7!VgW5{dz z`w%=w9Qb?LE9P+SU>qT`*~M#C4%t9OYt{}PL`@`a&Pf`Zq{4V?jKrRXMv~2#sIOj* zpt(f%4qLI3olTd$IZ0Cz+AB#8AfHrlDIaxeI#CbPr+Z=Z_i+U}Obf@@GFy3PJm z<>KF(4tm26x;{^e*&4|w^=`jjy=@lZkE&7rIiK}pU@(SyKxub)UNBX&oK88BPGM-@ zXJaw7hgL@y`s1cX!Ri69h!a7=^L-N>4&Eg28npi>3 zD61ZuoL{u}8_DldQu1_~{emUC;7CyuD&cIsj_IhIHle4!kUU_O74?(w_nz1hqEtU(^pHq4^HPF z()sMI7oD75qlWDr%-y~-eNfgd{uG#Q9>Y!QdEu}s?^jX3(xa~LYy2!TboZ0P_I2^5 zGyWoHwBbV6OWW%Vb`7R>9YV+26ulCtwi#-3Za|G5CGd@e0AmXlpNS6&Nj~(Z=)g%m zS0ot<37O%IC``xVx}(L>@M3c=(4Ca>5koqciIAzg5>NVRd=mk-T5Zblx}cH1mrKbxHTv1(nWO<{>_B*QENj)3=h-9ZwDT6 zOw-0I~TEeR#}+z|Ts3DI%9Y5`r-5RM*M7EBZ8Q zkCAn`ao3T|7SVGFs@iBnG7o7yvC!X?G1yg27PZs@DvYX!?d2mdm-z4K7J}{aAIloRac8Ig7KEe2b)ubZdUR zRAH4!C_zN`#x}YW;v5hfp}3M~7RV|Hl!?!j3(ug%CE`;OLNEpb4D2m%a{9A7t0bzN46w#Xk^-GF2FU-2k^*rCh0M0SSa4;n6ph=k)k0NH5Z@LP6@ds}?+^t(EfM{m|;x;d2m1&>C_b~N}ILyD7!vy)eHZ} zaRPIn?n-R+2eI~oo6oDbg>p$=QCUl1-hC%cU&GtQ%$3ypXaL?yD?6v^{$Jm(rw&Tm zeV8zYx)T;YKyN7OO1LW#)8l#ju+BKt9iSA6YXgei>?xW(-%uEmv>8G((B z+ywfu!Bus1_)JF}9CPt|3~4(+KlymQv|l@Qb21wh3)UIkQBStBzb<|>G1nzpY`)Y-UEG z;~`;hhc9h!!2rcGgZ5F_PjbPlKd!!Puvzp@qAZEpnpMrKA7#}K|F&TeNf=CyTXzHz zZ%yBvWVG6K@54m6BV4J+n)=#^_cdBS|3LiPzmyi->r$(IF48GOl^LI^qkugitX_>md+ySpuE4>6 zEN3x8MbC0U7!Pd3NCoj`{G&A1+S=Z7lig1KWt=sQXaagZ5lb4ZDN79@(f*006iuqI zra~!9%|D?s&EpD-09GS^{UkKs^;ZtCkjW?DS7M+ECdM!;j|ALbBp5LE@Chnbo?yaI zePS9{KkSiw2Bq}1MLvWil$x~@_d_N*Das``nC{t{l10w<+y0mIN<+Tc zLc;>_9-m2S3wm?;EEm@Tt4%ta>skmv(J`Fv^FeW8dmV~Tn5BX7Gr~CiJq~dN* z?S1*M(quLK#Xc>}c#U+my{lG8`%hN?XY+&Y%b}JF-u?auPLdQ{V5L<6VX7!6^HRBu zbj8zMUF`Ns8fW?})?2Ztf`~LdT{=cMgVG;0s?ZBb4U}P%)Qg3CKmjpjk@kdij-h72 z@Cai1L-$alJo(;a8ubUq#7H=^Uu9qezBH@~jzz|!x7 zN3#9~4M^)X1Za~LffJnM5jRV}bIq3o{bVGwsT(W=DsWaf- zV^lF{dY-OmTfRp@Dv+MZzwW zlEH14N&_KBh|f&m@{o}kmle_FSyr&XRV+^_P#t3c_zWWsmWaLIr0&f_H)7Xhd29w@ zdK2M573=0OmNS7viOyv}BBDyioU*ioYut-4U~c{243>+Zbo^JTBX%bI#v zC!~_B%gw6}jiyxht126s>XzKD1Az~5 z(eG|O@9qxn-<7=Htp|riD6oa#W8s1ig$x3CBs&8nU}k0^Pf8jLxhce26Av#=zK}GX z&dR?OjAhDPdxe%);WW=ng7yZO1(Ny?P)VM&7)8J_kUiMD$N}B{OLX(=8onR7k_>s7neiW6bY=$OQPS zk`bItWJX~6WacQ5ho5RCdG`|PuGP&6--bDqGX|UR~N( zZPrSN{qQQ&zr-?xwZkvB+Q?|?r7wmkSy?3xy)0{+`{Q(hgXn{R`jNj}EG^`jY~MGR zx3lR#Y)8HRWOTb-dNb1qf(Jt3kTml?1c(GB#3{F))n8BojR|Nb&!$sK`4Dp57L*N& zoR=qHG9`rugVI3IqJV%r9t^ZY*KBK2Gcve(Klqxt(GQ%^5Hu7bN3q?xXh1TI!6SGK zfWA%Z&tRukK+8Ss>tqGlzgU$0T}bOcD0;z1Xag$JqsPwNnl3=w5fPojIpgzyl`tmGY6%-XNIo)J`eWSpgJNLidjRNTqPs4%(xcb9agSq0Pf7R>NFH`GAi2PK4g-+}6z4YFTscNds9(X6M7nB`(7`}OO z=k;wSGV=IcG+dJ!LdODj8pz21DBbT5p!z6-^Mt}5fkJ_M@6j@k!U+mW{AChmp=g

      &lbK6Krg>Ok!Ecj4&b}!4)eHGXj&hg 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%0D-&yaA7pGatyYOV)4jt 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≪so>7ih&b{KaFQrIOH$o<_nKwAmw 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 z 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�R!u3e#-B!A$TYW1tColg6i@#$me_J7A8 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

    • CwH50(s}> zX3~qIvV>8UoVq$_oq**L0;_;yV^JI1ogXI6IiEnJ-yF_Kk2+!71KxHfcU?yhK_)=T zL-A>I@(Q55z*@=Avv@rGx-wTEfG8CL(J;eAAW)h8ZQDo$l9<9|LZ z@*i10C$iBnAc9@3Y{71WCcH@!`Cv~)16}7Q%X08! z`94PeDl)@}>C>DdB5nKM;7{$Y)01h_6x9hO?uj{112sLYC&VXgvdS~J?`dxRq95)q zlSv)5C-eTCy?n~O?t0>Vy#DoceD?8K7@zsN!;hO*9=4Xdg$$etvE+^XHjvTaUWhWS zuvxE5$l?$>6g6xJh#f{V5kw?Oe_MrxEg)GYnM%6NLq#`|{W%#&LP9bm9i1GTG@%E; zZg{NVLO@$$VkNBQxq~jEq#)_}DRn?!-%69KU80uJnvR-ohD50sIJ7L9(T=&gs9{WD zNh$A5KCiJTJw&(gK(Au;LLSQHE3Ngaza(ntg~)9^G?u7MzMXby;|@tCZZdsub$M38 zIIc9LWsR9Ue*IPf_xnQTW%IAY(D#jhIW6K2`0AD3Qv~eCMsY0b3{y33)}M6fxgGNF zbBjDNi8tRaJ-z9Cdib~>+MV#RS--9#>HCAdK}LGI^gCSJIEfNX2v{`@Ac=xZLkB}x zIqE*6^MY$pcSysW2?5X9+*zZ@bXwvF1YP8S>2EH{UZV3QFa(8A{~5c9bowTf0{eg+ z6ptuKr^n)a=kv>TzJxBiCIsu|k1}ySH9gfU5~bVvjX^XipYq}wTSxyWVZLS|VtxyY zQD)=PV@%s$w(c4whKbH=OGB_Z8t(uCor8cKyq!DiF&4rsue_T!}slEwc-;RyeF_gNG&p6Rm6&!V93 z^rAlTKT+skZ(#Y)(8zBf$8J)&{!%6E!@b+#)A!1EIZp>y|Ni(ronBSEc|5urt-cSw#15~7o;heXx7-7O;yHwo0-a{yYi-h7(xbN)63+&7URCt=ox-!NC?qVY; zGC118_J9=BS{k)z+y^V}Z)(=B%u=p$c9S=;>Ic(P@aekO9aYR`U)zD}mR>C)%|bWZ zY007lwgiSUx8+`p&+){qjZ)zgrS_gvtGrHRMJT9~2k9bMj`uN58=|bnk9e-Tg3d_4E{L?R;huuq0e>@Ann_R62Ttc4h0<@YT zBMS^TQ88tdyw1WA-kdc2w)2C?14A=d2O0)0Hi*ei1dN3tT82aeMx^X#QP}iwc1cL~ z%+X1}x2$&H>YDntmd89m;{3rgff<3x)Xc$`6OqZRqKQ^mJrFcWasp8;9sy@KzV3S-qx`|YhPC0f z*I3PypC4^_J$!qnigEAX`##-&nBzTi4?DIeLgI(%@N5bHT5D3VYxQnAu*PBiFd~V% z#cWmx5n#l!U@OgqI9W-n1SxQswXhA0nu$kc*)&B3fL8xmfkBU_8R}d>@J1; z5WxYwdT)-zwEio2>M~L&Bn1o0M87?%(#H>b1*2D*IU$fTlHt7PM+6;psK8)Z8;CI0 zYSx3UIlq|p5LcG}ZT!8}yzIi>m?5E#cr?!RB;FPs_hqiD!<-TK=88jcy+upBeJr{FVdIvX#H4qorj=kHp{3qcC1#P>GLUwP zMLi6bV&($;K;zt5ffK(T`=sGtUch?Mdb_9(3)%p6)dJhb+|ZirjWTSJ}k6F-B}jWwQ)+TrX@Pu<&=Ev&$f3`WtZZ3j+J=@;W4&l5Ft*|nrX~3P(hjG5S~UW8-086n$!vwojz)%WZ)Z+!Anm3nSI~*>d4WoS&N64p2~nd&N0#f`!X&m~I1@d4;ZW4h!Q;PT5kczRe>2;!t7N|#B-tGqe)pZ^ z5PTE1PxB;F@H4ZTw)85sp=NhNEM10O4m?R}0vxz*}-@vASacrOt=??X%{;-DKZA>52Vw(>poKIrUjx6zfdwLge{9E$!Dn zogF`=1$_B9kaUp3L=MEEkz~ulp}gH5D-Q$4E2anbChdfv#iD^DfwWSptmwSxyd%;} zw6bPKW|9%gq{`yJY%a)Xm|ZL@>atfK;YtD{auLajl;aW(L6=9BNN$Q%m)=+Rj3}V3 zg5EMUdf;jYo6LLn2DX*#QGguynJL84dJ2*I4IV%T?qhJ!Y;&Xr9w-n7Jo8wY&8qbx zFfzGwc)R0?(q+W!^6x!8FOTc$I=!7M4|z!=SLVlqE$mC7W?ok| zEpqMp`!w};Z`wA-YOho6lr4-n$bNrrHf2-wJ3Pu<6j>=;^3q-CdVFqn|M=M5Jzh%Z z6>vMAk94;N&zs=cP@R5Lp4^iJT9}6k0Bt0CLqd8O(6$FlZB(Q?6cr5$7lUlT)JrJB z=w@I*;WiqHgwmxPxpbr(RZsi?3T8G6@vaS(NRZT|rGzO!lWPlFx3|2C02-1ok^9E<8`gdIQE3-z5!KaJ6Q-XgQ$z~3sy{u}b;2|}eog7O|51 z@=)~khwx`n;AxZFI5VvdcjHJT(L9z4WH(hlLE^d4|4 z+hWVUmY1f*rQ)j3NNA)3^NljhQji$~|8-UokE38mp+R6kH0*5DT{u`V2jzgOM-o;q zP0a`t74Jt=HzSY|&}brtPMh>i)p!xRiwX`d(`Uj2#Ohdnp)zTwVcC^snE+977}MV? z8B<}?#g-C-r_(b$Kc$RoCWgq&$i&oHWuU*-3}cY!A_+`YgL%fItpxMNHT|?WAwyQy zrc1-Sf~}TV&3xZEtz)tV?+ICDtar0Sm{X^2)^qi7(0(53JQ5z#toT};qq6jP&91oC z{qg+1+^rZ?#6qL997P3}mAFtW!(BxQy|xV%-JoK_?T zpIjkvBs{%m_ALN7!K&V)yq+I7kq}A9%EccGAetWl7+5e`V588Z?gE3_!vbOG0tXm0 zX0K6wvQc9(MCo9{QVM2!>bwTgA2Qyb*P{-j%Mz2+G97EOGm{c`M9B*S%ii@qUnvTa zA@t^jqWCO+^KBp*q1}qCIFk=cb~bVhyZ!7aXIVyke`N@xg%pOe9A9m|ER4#0J+}$o zoBf?*E1)Lz^}K&#`{1K%2cC>M{=~@-&o>If`x2&+e1e2`@+1(RWl=uJ-2 zuS|bD!_CJpYY!TG{=z3gK>5T6y8Bhd+2oU+{4&d}>!xLGnu3%$c2~I>H4?ZPfKyiH zwM7f_hX8p14h)E%)-&-!5I(!h?PbJRu({NT*<8U7IsNcsblo!0yq_+v5&^*nCI?ma@w^{d?y5w{ zbS<{X8)s=6T;?$<%@khk{+<&~*G%?ORDJ7DyUM#_P;*%kUBi75GWOs9s^36HD$uDL zVU;9mZ#j~97bY_-48_EjI(LaQ6Nh z@=!#4Ebz`(t?1FvB#mO|C%WJmdAKr=bAV{#Jf4Jj1;AicoDMQ`ivnDbPobe=(a5xV zY#ofz3Jw`syG}Szu|?9Q5+I@E8Z*IUFEI$^y=T=^JDS*?c?k$4d%4|kNTHn5SByPS zNp!wOT7;DbeI$Z?UmR5(8EJ{EM^sVb@xb5B45pSuNQ`@zC~m(b*Gew=sbf2#Kej^n zf%fSmqY#v`>yIcT63xUVV?JliiT4Z9%Ugt@~4FfAVg}Il5)Sx7}cq z?PJQwI2^bRUN|X4C5Wnr3Fp<a$o-JeS7bV!-xA(bR3pJd%*n0Ax9fT%j_Dw&iwl z6^N5y1WdQb9ReN^od6G?jE?U4b1#ID-^|KoD{7lRmMD%TNEarQP;y+c6?y8WS{FYHOTwj{_9p-8c6IA2mF4U=u0Q`d6Z_uz`pxE__M;0d zY^qDO>RL*2bu;&i*~82-^Y#u3Dv@NYa8Brva}+O&Bq?fdf%6dc&ceJ|VI~A*6|J}_ScN6#gf8f*k*nD^TrpEtC)lssF zq#?BCUD1IxIyM%Ja+kdbjiAW_3zhHu6FrHNrbL~DNJ0p&b(285d1D>SGBBJJJq5G0 ztw1+LUos(tP(7`zaLaj6H6m@{6BxpkWd4~lU?*SDt;^0%f}#Wv*9Q6K2c<2_e4hYr z2@T^+pd~Ofo6s=CvWo=Zf&2B@15^D`_Gh_&XSd=-U7NCdK-Hyhl>D5_XwW?kw1!Ta z{;fYOwaImL6!$W{x0Bn(vUOg6p=-(-GgxZYq8F1`A~k)P#2^Rhn;I!?Opx7clVi|z zRBTfURa<=Z-BOox+^+W%nV09)(amA3-S?cD|34{QT2BT)Qy+kw8PorTB&q+GobF$F zzDPbB8aL~y8;y7l_j5nq_djuVV@|$6|EOtSd_~c%d86*;E()`4lnlVG$AzE(yi zlxnl!rh~=2u%E%6frH8sL;yNnwpP}aQ1mG(vja&&W=LRW`a5hg0pcI|=Vd@P)Ihm9 zHaFd`KoetR5FO?xJ_t2k%yaW(d11%+1AuXj$KppiBj6i47%En?IM47O=w9 zPh(KGtZmpe)Fo3EXeXi~cF!<4u`xqBh<{snIfqL}U)$7>qz4j&j^~ktS@P-G4T8$5 zy+2*E_Z7FCL@hElJj#``RA_3Ke&NdM#-E*4U1>vjVUsr7XFoGm*C$Q%*uU2D{Mxt| zv=_~)-7qe%`EB1l>DGOF_U4Ia@h*TiVCt&9)Ylv&n?q}n`i{5>fhQHjGz(ScC7Ick zf?xqMGcqWyzyqUIbFXUX41!u45IVuKG>$S8!36mS`QQR;^*t(e0G!C&Lsn7-L7N_w z%|~|WPK;6112OZ6nhq(OUAD&Vp@;zUGeXpNASgi~Sz~NWRtHSfioI-caDP|~Ss#X_=Gc1nm!6F)>vx=1VL$PDVcRHRHO+q)$!^tnHAz7tcn zls^99cf_)umEU~iA@Ip_Q7?JUV}1%Tw6W~h-X9)2P{Tnn!)rI|`~ErxA1Y{MMEQ5p z(QfI*)6>_)F|3bP%GFlP#C-NF%&F@-48jt-(ndRTvfbIb<{_l;V%ZXI;ne zP!meld?2G5PHV6Ak!YDw9qTHpwDi=oJffS>LRZq!8F6_dLP@2$HL#NC7-JF;^MRpg zkz@`%L=v_h1zYmkiN-T^@@BTdLIUlRN9iqr5*)p^O8egy{Xk=OFJ(8HjO;F9b$;PK zMxFT_0x-kUn$aBH(sTauRo|%`KP^pcnEftg@;1fEj|oYi)$mHW>JcVwH!^yGl|iR* z&c5G6S_Ek(NDhNG>rK(@^(EKwt1g4`ScfXtn))gK?#dghiocbf-vU}uu}U4C-Su6Y z+rE^eYy2=N#R0s7m73$&l$Cl53(R5y_)-b<8Vv+sfA}@^WTp`boPY+|h%o2!8Z&v% zY*(asc?5)sfr_C~bLj9g@D80GENqwGYR$l^%PJB=o&ZeJafD!Y*QcM(wZExeFQETP*4R$|-}-PCfBoaRcj*~9jiQ|KUzhU>gXiS*8E*f? z^G9Q6XX}~C`8*l@TLUB@ncUUmlEqWN{!8y* zNd`Z}P3VgNgqez6(!4N?^b`anM2DHF+sI?~y#~-?gBx5Q(Zcdzp@E5Lq3EpCz{rXQ z1nb<$!WiZNfKEauB12xDkel#@q}}^43~+Bz{xochanaHSEG@&OJ~-J(zLN(>Rb^X{ zcSNxbr1e-%dds2}R#GSWrs<%BC0dY`cf(tnKn+uw7gr)Nt4@U@EqV8K(>|Et&x0l~l&ztpOo-5GZ6ZIE4(6%E>=u&szyR@^rEdQ)<*jjfn|D zgM;>DHv#B)U~(M|+Fby83nO8BMBsBYhb-x5n87DWrx9zz(nlIIC3G%t66yPUYtptJ z5$^3c1c7{`#|}sn1I?s(Kf=D;;L=!^jwAk$^QN(v@)*-l27yvkrB=lNAF&nPzvYyS zjKuwnO%ABJoOY4ZMP1>?vI`k+KiNNYsD`Kc?;orYp& z?QAAt=U#5%O!)s;`pT#%{`c(#mSstoUecu-7FZgU?(ULUI;0!FvUGQcN_TfExzZ8~ z2m;a~DIyXoJox)R^J31Kw{y;1bAPV;3ao`H843`d!4Y4UIL}Bb{-`sXB9q=J@`z2% ze9PG%Kp10OcQ#954%xdq3ZeNO1rIY!GMCs{nI%E5^fY)C$r4|{~b$P$UQ8oN9 z^pI@HGjuiDLkO+56kL_HrPp6T7vuc$?5kgYEj$gdm00}!OgpOAQ0()w^_ip2BeTx_ zKj@%P;rrA3%iH_Az4!MY9#HY$^)>W&gM}I4nvH$54A>L55=G`{#jeB%!C0Sx2xuL4 zK+=#l5YDuP4F@g6$KGHB43LAYzQ(N)*5|(oNmNkWqN8sS!mv>Bj^Q=}!RzB{6hL?y zjG(awwq@-&2AqXMngIiHl>DtQPW)n)KwY>@?5mM^wmcS4#%n9M0=uR>Ul$j@MOJ|H zNU5j3Y(76nxwA0GUb$4gn$hty!rQc1bh$^Xqpt(fW4FI*?M*w(o9S!y?dW{|o5*4R zZId}kM03zfzrVe-MH6+4Rie5^BOUqPIW&AHMtPmyDV@Fg|FlczDc6!-+BhM@UI5;> zf0F{^N}eQ%^T`Nai^D&nk;mVe&oRr*v1RG|e%;>R`)}hvZU~9MCFKQ?l&NTX!6uoZy;8@RDSB+9xdCwsnHNZtrrbG4paMWa-Hjq0 z@{-6I3k`s9k|Fck2LLv*-=+%0Rs*spR`#_~i7PPmNT zXJ4jbFy*S*Zm>Ha8yvfsQk8ri`;-^C39Z(DS;(?tokMZsE*`fv<3i5Dlo>_u60p5} zWBF-gq+Y^43*VHZwnl^z{+PXhQpcoppe5D8eCv2c#=%0E0Sth}?y= zfV_C<<39-Dc~pZezVS`EoOb%uN~#X)%MuN@&!$|EIM#qA|J>HraNXyb?4)!t^*?n&x&OIzRwQ zAk!Er+ftqQY1;Rzdj%MftAOy-4JHkX1fvXLX{mp_WZeg4NwDq492woPU7ylVCJ&@- z4ud7hA*e34b%XDxFQg$RKN};yS78-_)r{s3Q2=&I%Yh~#Ne<+SnMN)goUSPHV~eXc zx@xSb_>GJx_gKEIt!7|Qbxo~7^jlUx4H^XpQcD&*(R9a^ziD%QOIB)W98BxS+2PO3 z{OhKe%WK*l_@aG|Bl{vBD;?D6Ic0V2@GK|w{<qR_-W8jX;*P_u6zHQ{Hc* z7c=wT9qle1(3Rtclb&l2`hfd4ts69<+>XY9JJ&}&%K_K_Gfsa?xq5Fm^KT=0F*QE> zPvq>JCQdm8!1>085C09dk{YD)^eqb*8gHQ|S{sF*Spk~k;t zG(u$~>F=zdHz)_RsbP-+5*%rWms=mzEPxHmd48@y=@el$G!djfnpT%yjU%BVNwxX5 zc!r&a(_U7$Uq|iQfk0=8inLfL=D!l{4o7ymmMza6m*3`&mmB^+M9)5K^Z)4}7|#@Y zK8X29FJZ>MF}d|k^RSJwTx=&*oBvmOws9Q?m)oyPjk_;gOn=pnT)8byKQD#$ov+RG zHuzke(*3>2mb$l+4ybp%XS#b@;NWDx z0p_Z@pggxHyB(7Onkw@47Bk1pj7Y(bB4X^xv^#mC-j6Z{L_}lR%yLf~cikCcY<@4$ znE0Lg(2xgqzpm()P{bbZ6sn&^>|zBQjeUvZ74v_-zVY5)-72Ts;W&YI_Rg41kK5vW zU#eQ~jnpH1icEE{A;VLz=&Bc{D$?DLTi)a6y9m zxk(ECN*5vLeWukn`zac9Bi@d-%?)Hq>MsiV92_q2$I;Q`Dl~vV7EUOf4C(19J_MkR zWF#$2Bm0Z6!(vS_-U92>DvXc|qKKgSh}^H$hza5h78#w~>bF2U*_emE%_)2wfXr7d z9D5RgKM8DBUdEFWBDjYt0T9er|HdvvRA(@moBX2`&H;pvqBWy^WUw61od;%|09LQ_ zRG!oUh&Xzk6CO$*U^WmPW@I#d%f2FFQD`R#z(GMt)Wq;~${We2Qo{?7VPK+`%Ml7V zr{2-qRndM>>3c$-OL$C!&mlMjSmYUiHl`Q`!$ORyJeEF~1lQXlY~aNXwr^usOZNw` zxV*okn^Wh<-+$^nL>R_0-QSA$`NuctjqOV583OdpI%5;*yGQN#d$D|VX7~VxsY`pk zHw#u@q<*&+_9#YR#ymAE}#rk^g(=|L*Tj zzXrVv{r}H*#jz(03~QBj_OCLe{g7Y9E}2ZQ+y~Oxy{l*dkWYScbF(Z(5`%&qP&tGO zsStZtw`Cv|u0xgk8&^hrr#gtWGw3$FXbGmpRM3`A;JY{MvGA_j*tHRUr(!w@8Xrx3 zmcBy%6|e2ufwh@d{tD+^$7)6aajV!HK*DH|@*Ktp4gMi7Pzc!V``*c~XvRlaO=KCq z-nF=*QL(lrhAR)*J17f(y0qn^PYz*yrtI}6Q;BIpO>^Sp%T4SkJM9dTzP~n9LiOEQ zmyOr=9KIcqJ~ z(dF4vGh;LxeO51tLWgnP{@!_aJidH0d%v~^!D6+9UMT0f^UE4EjsB0i23-kN|Bc7L zySuL=^&Y=1&Y2V#eSTv&-uokV9o=-Qyw&U7{g^4%hrZ76{^Uuw#qWbtTkluUy?0k8 zub?*fw|~CDH?B5b-M#aBOWr=NWBoR6_?zj|@`uD2fR+wN(0v|~$@C$NGJ;cKk%rmC zI{!fmV9qpK$cX!WI8y$dC#uAx(6{1XWKJsTl zv22}*TkqJ9tquKJdbT}_$xU8^jb6bk`oFOrzW9-nrVLY|;?)JR{PsFg4Ab0StQg|h zjJWF8s1r@m*VQ8z8mAlYRPpqVf99s;`{X-ee59CmYt-nfRCg^4X4YV;n_opxaK89( zS*STN*(YO~n(Yyag9|=>wP`(iwb?h}7HXs}q-yQHE54k5k&N0BW zsh*X{u8t`t*IH1S3Uj1`?`X{KMEyb5{b}<*PzVD#n+F?63557S8*Zx~jMHD3)^&)V zBn@Z0bIHmn@5OIUj}QD5#&dn%83-+}j}5G6LYmz6y^tUG5u;e1(Hsethzr#@%92Wb zc%1-YYYO0z#X}04)~BLa&I+z@UZIF$q`mAmz$AvIOf5^@EjsqH<`X+fx^D;{lg4;C znYlwDE~0Y9Q`%P9LS(TX(q*I5%$7vS`SVR>FyysfCBZIX+eKD^7BGW+ltMwb;*E~r znU)rJPUo6<_LBm-%?8R-5_h5Mbw1%ajl;<(UM0#9)7x{T0p{cGuDS{LPd^7Q#1Ex*l!LR&VCP=X9_@9qD`nvO)+x}x zZj47%#bi0Fa_rzu7}ML3Wv5Y&OsL>h#FPr#6CTL$WoVl58+fZ|h#UMgatkuKIpTS{ z>}2S>9wF4C%PJ!A%t*BvcWK7K>L<3El3CMFx%N|thE~l>-1J+D*`Ef@*30X@ealv*fEwHwq z;T@w-$WFDuZbqNLW+h+07%9E1l&{R-^P*YFCZBq=cb8 zRGp-?IQB&KrDqXhPmP;T&Rw&KtT~SRyl-M{cq98{6~F4(tbU9g+xN@luT{(=;^{3U zhbqpzgE`xbdoCel<6cj3!lRp;PnT8wxpVK>t9qxVzKcK0YmF>3yZj>v& zJNb=*pWhej+yBQD$06~)uZ)^`AwhG&!?f~DRwGC73yLz=| z@P^u1#_i3>XI3%pa{q(RM%K&xTzz`9*^_3YGOqQm?*1gzD ziy#Ee?4pLTOTMO%(I$c^27be0J2`oFmIlrh95n_Xj;yL0aX@|H3Tr(LHC|slz6fBA z%(=XfOlE9$p+hq|yqd7?zc|f>v>hWc~nA?JwCVUFA~v?+&UUf zUZbKqItMR35#7k0ZjjGeWIiiBv$)b0ow{vNLYV>op6fUGq51^V!4yI4bV%`R#Y4$iAs1-M+aV64c5C*1|dEDpB9jD?GH87 z%BI(v22ru-*r0XkE@OF5Nllg7a>7>4o3@Q}gSy(_d9uJ0p{jIsb&0!14{HO_VYkR> zTHxXxtLVWS-i&SXH6%Mv3blXEyl8E1dqk~=f4}v(oBQITN5OVSz3aK#Ap}A2CQVxM zZRrxyI1DfMlTzeXf|krU#c-5J8omfXwd*%S%nGZ61D$=6GRKC(xb1HZj3lw-aRqg_ ztSlDFB>poNdi$(|y?OcMefY+B#pM??m&P*9(Q%iRUrb7)m}ppV$G+;pYw3c*tm9-2 zZdq53LlLqtE@*cp@xCIhH=*hE#899p-4ua_q8i8XT5tIF+AXV}l+O)CW*&5$Apnn{ zN1UUTC4!YlSklnlfs(uTWLI77hv+3kRCaHMr(J^=TiLtn;8oGGjOpM*lVqci+R+5^ z`RtoDb9Yg69+|{;E&i|$?Fy&l@$(#RfChFdWRn)vj05D9w-{u?F@bL@>Gmnet}Z-R zpjAoCOB4CEPi5;iu@oLIF>M+o=*ZRpi2eiG!B{M@E4Z*?9qQK$OK)qU}a|vpM>T#6Vklt$$C>s*yq|PVY!jDkND9<&by& z&t80O#=Tx5ZP|!ZkQkzpsvhlBZOB|fmZw(TpHC@hqoi-@-4he@*(-h4tM|XrG9q+R zXx}|{GoKr>BjTxW;l73OSBUG?Zuu3?22oCDoHc$cv7!VE#Tv!fB{|IyINR}KL`jT^ ziJdbX$vig-;KTtK8P?`yH~pNCG0Dtp=zLz%;scir!_|uS5keCT&#R`grx&>%nyk$e z7j)Dc;p#eU*R&x4y=ulJ?D>ecOE*Vd(K*q#wulUcXByb(f1pr;0niaVpm4U8z>6CQZH5-|0$4Q7)*+f?OZx7 zvAm3#*~;fsr%hJIa3`@W;%l%l*09SNAc7FzDJKrp+gX!&&0L}gsHaP1?IU;>*DMYn zq;H~)XS}XMXg~68w#!6q)?@BRAk7#s+o-(P;P#HXTz1FVPZYbvtX%7DU|g($S3Z!J zeiw_x6I&c9FH*MuP<}lp*4`0AWy>bitkO+VB=&dbR7k~4A@Lkw|XuSe^mx7N$X;>cW-Q-nOhfgX9v}+lU7La z1~*$eAFpSx6e&&~kZ$kLCEx`$`1M2h*xq%WjW03}z>V^?i@^!)N5{9}3c5 zNxL-eIz$HRGyp$}!?U8@0>JQU?(+3w=a~jr-@H=y#>&A{#z5$E)kxeQg2F zJPEEr??les%iNtu#A1yP_&y4Z49BjY)D!1w zmMlwqe)Pz%hb8^?tscq+LY4gOc#*!W(gs{H!+4b@LmB5$dqsR3X3|S;^r}H=teKnB z?zKgQud}pJw_1OcmqLX))z^pKxjnwfW5MA%3mpY(=k$4L9s{<-j2g(2F9p+qVs^9( zl}j_(>n=p6$Qi*)h4A zxqEl?e7oS|h8Sh7RQ;>F`}?yU&tnKhY`qFLZXXC0jGGH#O(6=A(Xke7;>0yjxXhKI zm3tm7r7`i=PcLk!+~Js%22`aJBSOBg8dX)jFp^bc&_E+%IQCY9`w_Dl+Drem70;=j z%6`$5C>(^;p1egE*E43w=C-UvAN$a=e2Rd?ChY&A0RMeSy-(!OjLTov3{e;sP`nd# zH|*!YsuB=bg3MFQ@0%AAdYcj?`%g`c*s-VJ{AEwDcpAUEI`TKXE;oYC`+0S;lfK*% zlXQLMRXY8PKOtr}zc>66cjzuQ-hC`N(q#}SZ&(Qrw{v%>*℞@(&bNQJ{WXJwlTZ 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 Qut!xW*oBkXT&To2Hj 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≫~|uuSeFABDFpX%N8!JI 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

      lE^wEONd7`{D%ak9YQQ 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 z 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�qAdqM`7lw@Z?x%bh)l5&32BzzGtE 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ྵ?Q=L{_$PRe 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 GfBiom2t~sH literal 0 HcmV?d00001 diff --git a/new formatted matrices.txt b/new formatted matrices.txt new file mode 100644 index 00000000..c70e6c36 --- /dev/null +++ b/new formatted matrices.txt @@ -0,0 +1,18 @@ +float angle = 2.0*t/(2.0*3.1415); + +var cwMat = new THREE.Matrix4(); //transform for moving clockwise +cwMat.makeRotationY(angle); //rotating about y-axis, based on utime + +var ccwMat = new THREE.Matrix4(); //transform for moving counterclockwise +ccwMat.makeRotationY(-angle); //rotating about y-axis, based on utime + +var northMat = new THREE.Matrix4(); +northMat.makeRotationX(angle); //rotating about x-axis, based on utime + +var southMat = new THREE.Matrix4(); +southMat.makeRotationX(-angle); //rotating about x-axis, based on utime + +var westMat = new THREE.Matrix4(); +westMat.makeRotationZ(-angle); //rotating about z-axis, based on utime + +var eastMat = new THREE.Matrix4(); \ No newline at end of file diff --git a/src/glsl/rayMarch-frag.glsl b/src/glsl/rayMarch-frag.glsl index 4ca610df..8c33b527 100644 --- a/src/glsl/rayMarch-frag.glsl +++ b/src/glsl/rayMarch-frag.glsl @@ -1,7 +1,7 @@ #define MAX_GEOMETRY_COUNT 100 #define SPHERE_TRACING true -#define T_MAX 8.0 +#define T_MAX 10.0 /* This is how I'm packing the data struct geometry_t { @@ -132,10 +132,11 @@ float mod(int num1, int num2) int sceneNum() { float x = u_time; - float cycle = 90.0;// * 20.0; - float t = (mod(x, cycle)/cycle) * 3.0; - if(t <= 1.0) { return 2; } - else if(t <= 2.0) { return 1; } + float cycle = 124.0; + float fps = 6.0; + float t = mod(x, cycle); + if(t <= 42.0) { return 2; } + else if(t <= 80.0) { return 1; } else { return 3; } } @@ -202,7 +203,7 @@ float sceneMap2( vec3 pos ){ float dist3; // vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat); - vec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -0.5*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat); + vec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat); float bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1)); if(bb3 < .015) { @@ -226,7 +227,7 @@ float sceneMap2( vec3 pos ){ mat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis float angZ = (2.0*u_time)*3.1415/180.0; mat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis - float displace = mod(u_time, 90.0)/30.0*3.0; + float displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; vec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX); float bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1)); if(bb4 < .015) diff --git a/src/main.js b/src/main.js index ee9d2287..aa25d99a 100644 --- a/src/main.js +++ b/src/main.js @@ -8,6 +8,14 @@ import Stats from 'stats-js' import ProxyGeometry, {ProxyMaterial} from './proxy_geometry' import RayMarcher from './rayMarching' +//Audio and Audio Analysis variables + +//Create an AudioListener and add it to the camera +var listener = new THREE.AudioListener(); + +// create a global audio source +var sound = new THREE.PositionalAudio( listener ); + var BoxGeometry = new THREE.BoxGeometry(1, 1, 1); var SphereGeometry = new THREE.SphereGeometry(1, 32, 32); var ConeGeometry = new THREE.ConeGeometry(1, 1); @@ -37,19 +45,30 @@ window.addEventListener('load', function() { controls.zoomSpeed = 1.0; controls.panSpeed = 2.0; + + var audioLoader = new THREE.AudioLoader(); + + //Load a sound and set it as the Audio object's buffer + audioLoader.load( 'Dubstep_Sub-Mix_2016.mp3', function( buffer ) { + sound.setBuffer( buffer ); + sound.setLoop(true); + sound.setVolume(1.0); + sound.play(); + }); + window.addEventListener('resize', function() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); - var gui = new DAT.GUI(); + // var gui = new DAT.GUI(); var options = { strategy: 'Ray Marching' } - gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']); + // gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']); scene.add(new THREE.AxisHelper(20)); scene.add(new THREE.DirectionalLight(0xffffff, 1)); From 97699d741aede3de014002b50f4d1fa9def242e2 Mon Sep 17 00:00:00 2001 From: Joe Klinger Date: Tue, 2 May 2017 23:26:57 -0400 Subject: [PATCH 15/20] Jorb's done. --- milestone1Pics/milestone1.PNG | Bin 565011 -> 0 bytes milestone1Pics/milestone102.PNG | Bin 562312 -> 0 bytes new formatted matrices.txt | 18 -- src/glsl/firstPass-frag.glsl | 380 ++++++++++++++++++++++++++++++++ src/glsl/secondPass-frag.glsl | 27 +++ src/glsl/thirdPass-frag.glsl | 14 ++ 6 files changed, 421 insertions(+), 18 deletions(-) delete mode 100644 milestone1Pics/milestone1.PNG delete mode 100644 milestone1Pics/milestone102.PNG delete mode 100644 new formatted matrices.txt create mode 100644 src/glsl/firstPass-frag.glsl create mode 100644 src/glsl/secondPass-frag.glsl create mode 100644 src/glsl/thirdPass-frag.glsl diff --git a/milestone1Pics/milestone1.PNG b/milestone1Pics/milestone1.PNG deleted file mode 100644 index e910bf6b1f230b5d869d73567d9b8085b8b08680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 565011 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⪼%A&XGtj! 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

      I-YdEym)ph4O7!WrmRk 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

      S>dZX6UxApyX z0=@tUq?oq{Uoo|BRCgE(PohUxkBt#VuF&>N*Txh#>!u?r-7{MY38AR5@@`*twL&r1Rf|xJOsBN}+A@P#(Osc8#o|%S` zyqVQQ_G|v5g9*=?bEbSvJT2FDCDhs+%iuK!kJt-eWrGh-uhh@J-{;2B8=DI>CIVF^pXzG?)^rH9FQ#~3PQ6*q!iXPG*>4xI3p!~(kk1Fxvc z4NQNe3M>E$I3TG5sLDm!{8rUy>EsswcHWaXhK!vJe5bxp=sew7P!RL%KPR+0xH4|r9XEXbPE+w|EiNcIs^{~m1)2S!1LWLL2XvC?)K z-`r(?%fqqhMLSH)tkKBfqWTv#^hy-!mR*Q@IAQB+Ym@C1pt8P14+X{8DTr9V(JD6d zK4lg?QdP%Xa8R|lxk@Ly`kt5r{u`^>f1?#=lq&&^=^xqF{0oH$7}UEs{*?xGM2+DJ zqdl+#CzbhtSe`?R61grOo*udztQvx1%EsiOb@$IE7*Z}v$-{IwMrc3Rh1K-9>a9e~3e6XbJYY8#jE}VEI zo~aQnN?Tu8!NwQmI%GlG2s8x%tjPf5$YNswHg=LULFnqoIKnXpY1(8O0pHmdQX7Nwe_$^*VWAQs6#+m6L5QE24G02Xe6#{^_ zn*L8W@DWtA-i{{pt4M-bNGgYgX=93JpUk9F6soq^3*Odc7HJ?8Z%Yq#7Zh3eb#`~t z?b@AJVVj>eM?wU+Skjmhm3iY5FRwsgGH|a-(mkRS&Q5T4XSU6A%~x|K{%D+MrxnQT zhNCc%FaB(vBwk~usOIWOjh$S4iT{Hcmwlx{5$mU-)*9o0PVVCGe~j!@)pNK_p#VI~ zM8o3$?&jJ*y@bq-8-IqhP1id4{M;gZWo*8RxTB{*zK&gx6~B~DZ)RgH4%UaBq&L#N zWF!t5BPM&Dc%stfGJ5!IsNsIFmH;*)_vuKowyk20)yOUMz02==!}_gm~yn}wP*VMTxlR9_viKK+Y{Eq)?@?E z)!pYQ3G=ntItSM+8jcc=#zXerx<8o2GQW!_v!W3yuw%ed)--tN;s2xVy~CPL)3)Kz zq^Kx{E=56&fYL;zgutMJv;+()Dpf>f6r=BiY5D$wkMubI^bcv6TYzK6gSq? zno2APhyU~>dK;~sc>uw{5+fe*qU3dW?%l0Ls}jsA_k|)JK?#B-K40fJk1ruMl6{jdwFQoJ-$yjuxS2Q`rf^9FRrEmp%2gh}a9b=F-PJ zmKbr-e77@rouFc<7u1h-n`37z2%B`++IW3Q8}U}3X>O+D6Ls6E;e9r*(aL;>t)ad@ za1PkTTHO2-55xN11to3Qj9mEVxNd(tc8{EOs`J=;UX+<=n~KCOF^XH_rAzhtXXqiV z6b}OJl~H_viQ>^UdHCHyVdb~QUx2U+2*i|$ zyu^W?f?4tP32C+fCy|m)^>PcZCoL*s{RL4sTfV`_r)>v4KGPK$riMTYmfdj4us)X* z76o-xaYM_@+j&7Bf;yZyX$bmB`z~SS^va?T`tXDDH0#P&7Z!(m$MR$Hz@ATfzJrP; z_(q56U4`vAASyoYlIdc+iC4u-Lps&$r*HL>H-($L>MCN(50hj@iHL5_%wc&17lTI> zwC}1|6XT{BlVUn>kiM==EED1XEOOB#O)Sg%?H&uHu7zF%x3yTlm4_*tb#e`-m#Aa1 z43FCGKr^Vm&^fi>SJr;Pox4&$Tj#g2YG36jB_pt*<2_7ZcRVg`NG-7lm+lWFjA{et z<4{qs%Y1NuG@>P2;X?3NkHyuBhHlQ?p`w`8+pGNse<0ZWhS~k$czi!sf2$k|$pqT$ zzc?iP`n!HOR_B>I&3{E-{!!`v+c*A=w)gLENW!hei2FZvfXX{)_RJG)I_ez-E#wCl zw{{;N2HE;ve%FL`v6hjE;(gE@Tej|KZIeDr_|h={frL*ggDTgPLoz>I(tRN;WRn@4 zc1=W6MOQ4NFx&+?aPp@em5tI#I~hjdH_`-^JY)*A4^S5y3dkm~28NXT*CF!Nc*O!dQe7_V$2i_ zWR#DRB?*;f!1-cpIe*5-Q(B7y7fv?V86*bNQVgE4=g2p^>I?c*5Uvk>1|g)LdB}c# z-n!(q?QpS-nR#87AVi2aJ~Fl!Q-^NIIp)yH6#vGLRL020`_jg9i1c8jVRK=;rn0e0 zjP|;_+d(u2M@Pyyfkc~6T{;#8?qCt)hhTv?-cdC=xM` z6<0gycCOojnKJZxc2||EQQu{=r%MWHU~Il#RtyNuAU79=2Kasdscv zpY}MFHIjNl=kzI$<5{0mJ9SR?UUbZ!Px$zx_+eXv#RFN-{Nn7kPK#dI3`dWUEcw)c z13kw*N_5_lP6=ApZKes4qPM4K&LXynAb$xm`RHw6Y^H<&*0Tla6?z%P(7O)0_wenp zhDhcRi(a?3zu*@k&Fe_WLor_Z!Uofz$7ptCd&qEhC3_h$dzBio zlJ=q$WQpz{hvbMZzU9qiI-1f$`iY-}S5#L5Q9ta@4ss_`Le@gi3U5w!?o%7Dt2&q{ zb9JW~gDOqUg~>e-YTU!j6U+^JOJW_}CBGPT_HfGOA*B&#qp6rC(A@23BrAd|%Cb2I zCWx{hi)9wOx;hOBr)houh?UFT*;oqI?WO8}eEm5&PO3C)k}v zR|Xc!=NJO6a}L#j?i0oJC(N)u%cFf9RE(|N?2IqO$MoDutODajn7^&JimW{Ta4wH= zs@v_slq+Maw-N9DcWMWJyX|rSdaPt@n2}_&{JA1@ellpuuThSl$a0C{h`-;VoXJZ# zRw{b5MmWSpbQ@`ysd5cjl>qyS?tc6hfe)^|ua846`}SYb^v#2aZ?hm(7A@cO1DE|& zwvQu4nYd4V=3&_uUo`9gxss+aM*)hkY`19^bW68zQM@#Vp^d4e>L$RPjG+M~M@&rjq~5^4kD zF|^#geU!B)P3$qn{r3WE1$V7Cntv$G5}$-;1YEW%0U*Ro4^pc>e>pDW5i~My?Rt5! z;dCG~1!$q97!AqwYj!Nq+?QqP2qG5SPy%*49&MQ1mgBG` zb2Z$@xk~ztq>Y{T#h4?ZLwSJ}iAzk*8&i9p%$Zqsmka{Ec5f*!VDaSwF^yBlaG97z zhIY!a<>6O?ysneHI-u0NXDso?GzFBe-a42y-UxhK@FLL%Sh*bU%M)5p8pn*Xdl!A~ z-cNf_L)QGE4F3OYGxQs6yMb9Zu)xK=AvpxX_V=`-L^U=IpCGkje{sUWUM?_Vw!7h) ztKQ!!0Q9?Hk%Y^w;y&vOpsBq) z<^stxF{xojl^WCdC6?)4tcp zYbzMzipFA`1nkxpl#V=z3kp+#kp-X3rpF( z&x@b6%~+_(K7UsHq;10DlI(NO;{0~5>4oDxpDwy(TPGYi+0%aUQnqKp$Nb{AZHX2J zTc@5Bm$wnNFwOm7dV=U`n8QcNM7?7*RJFSU-`$k9JYtZzV2f)PLhvAUeKa^xOJ|eL zU$fftx+x%0JGTCpH@nE=^U|&=PKsSEOM?s3hQdgn$Kqz?;~4$97ikO15BdTFGUrz3 zuCM_B;@Oj(p#BsSl%=M+Qr3386*AW^Zg3rzcv%@cR-5n_;#0A^ZXov3YbH$ zySsLD=@&!Kf^gB$Jy-BWBCUdTGFffXnLw@L<(DE>Ly9J@=fB?kK6eW%FXYNdDDwb? z5-xsG)(eK%NX-lHcg5|g4V($@tn`@ym2vcihNm2roYUkS{&|Q@k+e}#U6IPTak4sZ ztHg1y*^><2{$$8~eEDkkJAXsuENeH%ZcuoopjG4k^3Jz`0q)uV8wn;q45CA#=W)U1 zxP|@nD4Q#-!9Mj#dPDSpn5+zGt##`o`TTjqMMT8HV+jIa;D*-p*(-lI<`}Md zNyu2M;&sPQ(22sl3RsXc&xXhip%9_`etwKEg&f%}ow0Bd8@y|Lu4az1LyoM~qat6f z)#CyGfMlu+xj8u?64zIw;~F=H&1+_zM|AS$v{&)0zRUza{L-u&L zt*POHk*K@^qAzE-178*BJ1QJO+Jux$Fg5gFe-o&jB4Cb3)5nJk^Z0TkV2uHH+USo( z?*%-EyT1rI?sanFwuEA0UVz-xT&ny{nDf4>i;eUEH=KyK>Ub1{UoQ1F>F~UAW|^(3 z!1|e3qt0&X#bnp+e7382b4L?`n%6Q!#?Ao;wJ#${D7T2_-u4yWGdva~s@N@Ylr&p@ z2&!l#g|I$e9W5k5p5Z43N6c&%=%X_|?BdIKH@hmj43$FrdXeVhq5 zeMFxYSj`Y@?5rvXArHUM@Jg?RDWK{|6mc9aMn9*-=NAtV+X$H4l|>E|tC}Xno^Sm5 zO_dz}jib-jUWp7a2mbyQ{>E_sHzvRDgXez^(D>~`9D)tTNjaw1|dK9VjdzsL(-G)d~oIZAf_By2& zy(uNaoJTD&KF&>5(Ybm@{!)}>^_E0GxuRICUz>NXw#bKhYAm zrEx^Y4JkBHJoA_+kvH>a&YUt0y)K8UQ{gAbRxt$>YNgw|6ws}qu_8-lpuDmK8%}1XkOoF*{x(6#urM6V z_((OhbK|>$9ZCwoktYog2=p)ca@*Wp?5fcXyByXXmcX9v&n3074yaGV5UHN}sv;$8 z?m9gl>rn6h&S2qxFmU_<>iE97{|_nI{zkEM_f9rcL1!Rro4`fi-t**Xr}X(t;u6@2 zPaZ<3(s+7cw4y>L-`DMsxA&_|rC>uV7dNM48=C@zyL@;Pr?7I!X1*9+A`_QgoKYyz z_3DLTp|IG4WA+STn`#e?j1**@p$^YB%*I`{Th;s7ewq8F^tb;|+2!=Nvsc>$7id-c zbqT;cpqj*MUX~$U?*>bh>C?am1$}`r(tK32wn%OdKMwiX<>x>vz!Z9>ipX#P{w^g; zE>U}y_eA{vslW!hqC4%iKt?6W-`aRs<{osTK0}WCAdw}zjH}MkzM`Uf8D=H|Sena^< zP!q=*MXKbdwTSWoXPBl+!uTd8eMyfu1)R0qcz`=cqQ=fes182PB7Wj5V8wjT9*a2k zQ&znByZw*sw@ExSSHn-K#vH1qPRSnS34+-0=nCBb**_*l;gFoHve?6;Mds*;+MxzU zG@41%v*haMUW3)ZD%25bwzDUlyEg;OKX^xfsVKpe%)~xWCTK^TPpQ@DV`2H!sc8(% z96BDW%4XREJJr*UPOToSVP|zG-RsEzTnmQyFSKB$ehFUs(j=N=N+n(f@m6;|PH)fJ zZAZ}5>KO1pYeKV}wv^T-PsStUjz_g@F_q2MrSZY~Hk45Az7~{BUE$5NSkbqYDIK+P zQpEE~55C=}&YRdOdFhm}Hr;=;@&Vs-=j?EjpZ|BV2SFK}w<9pllt$#`Lw= zEuBoezLQMhjh_HTD6Y3?ud}ZavP-!vpiwiiA9I^ z*tgPYd)M!B?glLSde56@@Am^bCXN>#x|A-Fd?kC5Vt5db<2B|XgkfrWnp!oSC<#{7 z;#@6bA91_P>aJ!x1HHwQLWA=jSXE`KTh+;lI3)zNtA6f)*3a;nysaxcvNA?ZNNc2P zB)<^M7USA%nw^47{iF;r#}wgF2b=SYNbbCHa#)5Us>w@}_Le1i*I|Z%RC#Ih4Qy!P z-l;5nV3*hcabTL@>~xKKmj{qjXfH+J?znb0a~9ZpYk4hV)6H8X_s+FeH z9vFn;tE43aaH;?i;QDc|bUDlZ*WDEVet7s^cmEdf{n2sp2XGeIdK)jQZ4Opz?){1a37Sg*lCR_8DDA(GSbP zMuSxQm|EP5I4dj0*d*0ZMPIApLVOqxLPa~l%b>9tD8d%GEF<5j4`NHxXY(Q!fPVJg1e6Jf$ z^%^0~(r9rg&JlxZbV)-p@)Z=YHCfuGx?<_gDP{0>I$0}QbTG=pKTSyAwHSDJ1U<<} z3e6lkRF=TvD+dT@!zx&xzRMPG`2!UzF3%LkE^~Z)8aSwM5#P({5 zsIIk3%l1jJ85@A6+h|Hf=v4>=1!zSpb_T{*3vt3<^#n%>N7 z(feh=QD9XP;&6vI;FE?3Vmlvls8D0`#RwCD8x0(tYNaDt82a?kEX&YOJf+gKBs@sL ziI=dd%Jf(nKDKW{|*Zy zQFr*SfBoOTiT{uy?E8HCK&P7Qz`VE=A`MkK8+$P4gX@{fs&KiX*Bek|^rX{#9K1b>{0QTzdc#wWg(>7g ztGSRluix$Zoq6In9yPb}<}^?g%(a0%xRyFqciQxD69zs&nc9T4NRvO78d|i;3=TM7 zCO;z*XSG^X9`#pU>i`@KbKqi0Zv?i45h#brysh(gOppBf`bP4U5YRcf|C|AQy1HCX z%YUNJ3S?9kdQyiiFI>RZa*>h%%{we7CQ;>kvNMEN1VYfHnVaQYjLOZk-8~XT=*r^d zRUq8xDnbbgcu=~Xr_Bs4M)qTMxv|RG5L>?lTzebxkd>-&iYz`cF4Vr{%9?bjdej($ z#FxW9X6oij$+NYI%DIZF%ZY&flxLjbJo<`wW4`Ky;H_gRwJX>SN*nx*?Ou;9&E%>c zFjmg#ZQmIo%(%(eOYmb>U_FBz=+R>Z(>WMXmzRKcgW$RMX~d&k>7t8x_)5N92z*r^ ztTqyjP3>L@Srx{|DACAJI?>T+xnX}=^q@iALfGp5MB3&51|a- z9!R@3u%KVHVyw>eFk0=qupeo^sS~nK%i>(rH~P%R-C&WVZ;IU;(C4MTOUx)grT&u^D8LRp`?Me8}Ud+=*oulgO869w=v?-I2He$UdqS($N4X-DreliM$!!qaS{v6!YaO4#Mg3_AE8-#WS^%QfG>1#+fd8#iLW>v1NTLgcLq|(Vn1OP=8yZAPB z3Pd8Mr*t-=-U&3!rj+9h!{*id6>lbl2e==k2~QfV&~C@097l$$-dz>n=Hg9rMskEv zrG~mS8kzh!r9EOf+Q^ZWhNT6jj>0#g7yJl*Jd1hgsEGZs-69SXQd<=hZ_85Ak-Ms) zjHNLE<=wBaD(J0>))vror1?}o_lVenlf69Ibz=fDcG3-Z_Nq;(BU5;(QT&bZqp+xB zmo44ls=acE1dW#Y4agO@dA<1nye;vjn_#1KbM>iCF*HsUBEVb*V(>B#qEBCaQ5xPz zE<}WQloiLGWF5iQju<(YZsRJBKe{f~2AY2IU&RF9N6J6jApK_Q-T=HP{(49KaK2;+ zlK)XVp@e|rJ^dF^S$>a8KKk4)Ufy;j@n(A-pCD6%A1xnoXcw`_H^rFW(Fg@ou+bz|I4n5yz5-%w8HPRYYrTL5-6*0>>jMg35+ zUA4-pV_j7OZ{A4vC@{w(H#Jrom>Pz1OW`B=XU;7ThkbLP0>$kHDeQ^-WLNNn8NxNm zC!bO0p8-^0@cN4+y+OK~Up!Wpx8ntlGM!yC$YCR1`pzWZ>~zN}AwpN5DLiW4y_;9u z>vcOkQkDv^(lVQ@SDDNfY!JU4;dW!2 zO+?n4a2fpk(fXy$)#gMZM<@TxwI>y#PFZ}pL=|Hd{RD$6Gi!@MH{=8|x5E=A#YC2P zuj-$xb&tzUE!kAG+v!4n`>epO)X9rJ5ia!e&!rAF+@Wd_laG(Hrln zVG^iZ;9D%E3hn5b^AxrpXoArsYBvfKXGEQzk?`22o< z{lJTRx67KEcLOEp1}-QrQkvy)!)7T^zbuw>xZ|h0SIw{>`XlVidRSk7lfQ^Ef>u|N zo<0d?%v*xS*~!znF5<6Qb?MzeS2fLVWT@x_El4PolxPzkjABnCfWhILsh2%s#NRuD zYGLyDX*7Ldmt2b*R%y5YdwvJi-bS%(O(l^Mt>4@Nb&^CuE}oUkaH~bK&K)7l9y#OAokai`v;Y z@J1U|-ure!{8X=pC^l|BgPRvnR?3kEQ{!FVw62imDh%7P8m;$5@PJsR=0sFiBuZ<` zll0}G9Y)CIM$Qh%5v#b#JXS$6bwvg4gXz$Lf7m~fr^q^tnaB^Xf^^7j({Z{BAIyvB z$W$agm^Qiqv1awr_pkN_2F|@tB}lQU!EF7JSACO^%my^04^!dLAZILUCcjawm+$(_ zPO-S&M$I~v(2D0-4_e-1P_AM^*zijrm8mqWGmZ#M$+9-!Nh@umW z%3MASH%dKAa6a)h(Tqmk8HW-uT5n8U&Br`jeHS!amV{bcxw@Dq;P{VR(*89%_V>R1 zyXVgTF%|bmBFB$>i~}BSz*l^D%*C2Tr-^^^=-&WYnA9~C&PtE5mOCyEV+v$wFAsau z22iPd@Kormox|9a@9hCRcd!Yor!{6C9LI@zl`bS$$47%YZDnj4A4ar13+Ej{j_ILpKz`Z>N^I1iOoEz60QPwZlV{bc`Y;|}6 zButAy`ZD&sQR9m+Jas=oA6uIXgv*H@*mmaXLXKdM?UuEQoy@6~z^QKQc=$<( zP?(W>WR4rn7-nBYDSXOC5Y}yfkeS%M9R_Tq4_vR(mG^)Os=%V ztMfBi$HFh?-*mfW9EY_UvTx8@Yn)?j;Y0~p5B>fS|Fr{i1BLKUtL0yR=%1y^LCYJ8oW6Ec#*XPz|ZHJ_OjyGA~^@gq>&;R*n}!ln$3!XjsEW;dIkd zf?4En(zeo$BX?)TAHQHcO`IrEhA*s4ED%U;j_XI}(r)O}-1Lp}`b4f^yi9B3l&K3iddYiZ^K71R%v5j2EOo{6q zLBOTV97bB{5YIC~MlzWVWCmu1q!mCt$q=%NLpi!{WyLDrjxjE^o3mx!yZT6cp=sPs z6~9$EMY45gYxLyM*pc*x=rLI%N_Hd;OF^g~y%>VK=5_kk!*AWWGb^X|iN1wlIa^rfPXU@@L z$Wt7(0GW(nZV`zqbO#>!ezoSaYj{$Tk5-j$ zIclaw)&7)MO$KHOQu4r1A&OLzq3)m)Y!25+OlXOZGZDD?KR>cHI}g+KeCiCX0fzZ;9juzQqp#y|6-~L=*TLP z^tCsY2x=ames{F8fYHoex!e-F53Bvh9{=y}oqyC9{TP$*eYpI0*GAnx2$sLk7{C7g z-~Irov)G+%YZI9v=!^6}txpL#3#_iY%Idws%9g{vUkRF5Fi{p-m;6-t@ zyhC-QY!VLhVy**^Jdqx7dHIDSIK#-57=Q)%zI8sgoFYx1`{GYRsrTt>bOwT88o7B) zQ|EOtNZhviq#ZG^d0q2Hb9hb{b!^H_AARafG-ob(y&evq$TD*yyPR!bdd|;)q)ezxx z*zR)jWdCg1*d#NrZ&x}?uRJM;7eFgKHiqE;>EhrPo+pFH!kxb;KvGMnl|)I*{Tedn zPfFPL3iq#k$$!}w{oBpdkD}v$a7=#{#A8jagig(we{$d<_AQ)xxey(J;=@`{%aHGG zF14E*xSF>KUovuyIx2{g*1EkQqYTM!Yzm8GMhP9m%ClDq*89AJ15^;d&9w-{!dU9U z5;@$gZQs401$FBIb7r3+0QYt$8aSNo73N4r^*TE7Kj zTur#ppaTelW^ge=*<>D$vYaYuN#g8V?CX4IjXzkLAr=3zwWZODuVd6Vd>|hnA<%L3AnbaQ1&@t8f4for z?j4c29c!GLeCdZeck|QK*H+J5K)oeSho-QNZh*}aE#;>Q!HNUar-xvXK+z-uf5>@d z0FVl@?qxwCl|5otV@!G=#2xid?kc4zY_e~*(W$6IRN(Qkjj3Zz-5psV)+JIqzqS6= zd%)Wj0OCHlsoq|@Na3zVwxCsZ%yFZB+}Y@VjA{L~Isc~})!)o)zxUPvd64_Bv`ngo z^0@n#oV^-H$U&9hP`Se+@z5DxIxuga4my2o-R?oCy4&{ib~&nIJiL!B;B8|myXPVg zjwB%&!IAj2zz1D{y`rzxE!UoxGdYzlWX~=MzsJfC8hFwP>iY6=nx{84lH?x9z10Ep z&B9N*AEguhkmc`KTgjs_riV$s!dATc^(-V-)#iHRZr%Ayh>@gYSW!ePg~V|C3>$!- z^6NWu_BpA3q-*Mcy8gqZBL>JD;kq z3mGI@52M9z0Q&*Y+XR%L8*MyH~bCDne) zc%;Rq1HrlN?-CU9<}PM6${IS+V@**ff>rllgEjrIi1~4B`*(}xuY|E*`D7Undd}?O z{vx-OzX#@6Iy?`IhGT@R?0Z$(ljp7?V|oiU!p{=c$6u26zX}bHhu0k4UFRv(I$v{8 z5wRG?E#bj%e<~XesqxHV_&AdaG5L#Z_PsAvP1U=c!mn^Eg{EPSB7|i9$UlIe(R&4ZE0*RBD4ydH`n1590&|p1Ktm88h{+_p4RSbfF{WkCQdvX$y5O$J}LRoXN8Fp z6BN{%-pmE*TCz(ASqNnRjCh2XjiMV!9#LG1QG-T*=&tJX@z&jv?9^Uq>y$Q9v~vA6 z+UBlsUygWvXc^Gs69s$4(}QCsCfOgB_z2!x!=rJR?+opeVAi#>?sWxCP-EBApaky> zGz(L-d~vM3`$pr3!92o`eb5gaz`uf^fAaFTa`zYM(KpwYZwio}Ud1;eN;hwSFERdc`Y=K9zepKdoeMGM;%BQjJ;&&nd}i5)RA1B93N1Y84tjNV&wy@ zC<0Rl#6{%Z*3Cn~#wmz{YjOPmC)Mu6o|QkG;1bP@@+UBF28iAfvZT+^ygT9Ep*j=;c`RZR*9bPFv6Ae;b~mL!z?ath`_=k`>u z>tl z2>xK0?>bb%ACQFKI;`*9)4#d`{1ILF{Y=RwHH{RShrBp;gR~fJ9pVf9Rb#(uI zXOEw<5{4{0!nZ;IF&u7JXZKD=v zWIdl3KX3bz`ubpxt;dBd$JBs>J>>Cpi?KvNphp{@4suvxiKdl$`Ufv_Do?dOvlgTV zHaQF3OrFuzVxT^Laj82h0{dEY2k9`X`9Tzt&5WX36<|-@fWcey=T?;12#~_wI>>^+ z=CbA({s$7g7`&>EcPb0ke_&gC%Tm~t#Vc`h(oS8NDiRbp=N6-7SdY{CqL-hnAUjWk9WKazW@! zVN(}+?N%jmgcOSTcG9dn)5JiAUIfVwbnqgO>?({PuD0jfq6gsg39yypspT zK-*#`;jU5d0|8VIa`COc;gq%sAbg(mr1=#&moRQj zFMiTMWB2lQ58SXl!`Z;Wg_jJ!Dyo!37??ib`3SLLA=)SX>OL1#z1V5m0Wqueo1Wn; zQ`9y$in(CDAaVoBtk?)s&}t<4$S115;3cS{qBFT|mqwhPPE`YWZJ754_FCHuVZzbdE|#)Usp2e~iOGA7tK z+Z`ieUvDPu#_pL0wiRzlSx$GlKGpbD&BZ96?dag_C$>V6_j|{#{~Uf@Gjq#e?E5YUg=A_WX!T}D3WUQEsIwPG8^_MlzKtM z^3I6kL@_2;u%4$VdC$f=BGGY|5OjSTB5tW=m$L!&Qw{HO6s)@O#&!E4l`NnZ?>GeP zS+uw+sH&x3%1{@ur=165Id(a{j@zm(AH0s@Md_Xz6XtdW?!AXoi*T=p5V+y zb*&yc&0lNA%+tkt2mAweS}2@A)=PVQ*5jNJ8&qVg26~H_XU2D zC-~0|E>&wl@(pL9@|On<_*X*@gcd}^-+gjCOnz^tNSwg4ea$0`ocMK?6h7ug^di%6 zFqHO^whsg3Y&x>@=YY*o{_6CZ-jI?Rc%@`1&PAc1Jo1{Nt}K<<%(OC z{LQ_(MMnGoX(HGUef{r{zz^)gKfL^d%=d>I^IJ^M53l^8hx%5|WQijUBS9mM<;6z?E+GxZ}mPnfc zW2WW@{G?$*%Xr73jeqL4ec~VvIysfp?I?lb&+$;gLOw3EybTsjtb0>I08!l~PpvC$fO_xHP!BUb*#A)iHuvq6MnUH* zRyUf>iQ9l}DQ?)1#s+W7oYk> z?V8J&3ll@2AV+G1od*UETKVaL1gr^1 zT|dT>v6ZNiGXR2~I&W?Pk}<923Hj-Ffw#lyA8W`2dt5pv%5zP>7M9RG%zN6k!!EJQ z=SvqV>A}-k-c)bHOmpKnv2QyjeEt2?a@md7Sw86#@8PTcLYB@JUGrfMqSGjq7T;@ca3$4P2s`3RRHlnM0~PUEqm`wbpoR4MhFa_@%96vmbw zz9?%45n)CRNq!O^ud_vJOoks9gYW~c-^M{<6@)~D68z!8%7x=vCKgiC7w(=2l&hw5 z4k;(TZtrTm6uuJmu6<2Dh;pufdFX5hIp+v5UZBAr$oTbGQd0}h5c_k!fJ~WS`HZTE z#IUY}U<=s1^HJD@!_jmj^8)3dvmMDixr`jmTEW773M0^Nr9th6orlwprO1F5@N9z$ z9RDbJAsItS2W}|BWJ;N>miw?(!_5uSPd{=v!+ozv5{2)XQ4Ga2epUFone9cw(TsR*rr}ZxvOArv#|<8LQg*`xH8olUK_fszS(A!$Va?!3E@+htR$Y#7dvy5 z)PeUA#!e)~Dibwd04n;sRjDP{>9s{4{E`0bJFls)&dNG}$q~A4sRZ1C30YqaoF42^ z%#tw^wltI-ty(|bl@wA+>?+z+O^@D+yt}-8B~WOksGTUg@}~X&1%B#%aHUqqzDdp* zds))ll<7p=KS>X;zxTRM_e1_QQn58a=)>7?4GcqdO;iXqv_$m8h5;o_Uks!^26-`D zvER)|L?9{HkhNAM}b1l2V(<-kO$PsH^FO{@YrJN0_R*fEqYSrHO#vrsmCznNx zLG`9x@YcWZ!GmWP4=NI=5}8v|T#nJEWOR^puM0E9*K0xvK;Lg+HoN)6qpK*&+Mb*{ zAZjE6X1tzBhmE8SXzv+mk$#9V7rm9jNOQirwFcUj_fBOU#v%=iQ~0bS*Dqeu;vfIM zc8OneV~&J~(_lz-3<%zgVpy`@v2VU2h!f|QsDanI-d*CW;)F6^@=h>US@JG+C)qax zoj=}8Tbn=mI)$qT7n;YvE-X>h~R-1M=4xletguX$VZ zsxX@;gNef$UKWIlWnwc5?j=p^OJ3tlJn{0>P7H{1vtz2bJVaD=F-d|DI z@6FP8mcwry)A#kx@7%8cv10zK^wjUH(C>_jKU)NWt}ng&OuKnE=P`ZJibVdf|JAf7 z-B3G_g6(~FYFwV)jb%*kGv>KJuu>Lp9aJ+0)Oeb;!fCAna1~vx>$|2Z#x|dKiittB z&R>LeBw%>ev)vMyb)}n3M_r@DB2^^k?=aQkeO5*^rUr#?MzX=irztAbZEZ$cU1{JU znv2k`JCB_(g-b9e2Gs<Y!!m)EiaMHOaGBKq(U ziLCp@qJ&@!?_-`0At`?0vs)xLbuoB*g-~inD@9&L;^^u20FZ5fqp=@R%<~l`8vF}% zXN1F_ina|ejhF2(i`qJv{48Xi!b{9~sNyA+!X+`L;^;v__J_yY&Z=fODL#bKG)Ad< zSb3_J+^aejKOR(;?eVDWYL)eyfRe^&q@<-8=}vOsuhdsU zz|yDh&riaipQ9h(v0oebAA~gj7353LyS)Ksy>tema-&zocCz{Psh2vLGcVaTLplED+Uf_~GlEnA*uz-G1j(yb9dJ|Vn5-&8| zBdH67X@(skoHxVrZWANw&Una4ZfupnS;()wR>+7sYkbPeQXa)3SBBL-q=#E>AoYk5 zd|}9df_1<|^Br0Qn17M2OSUHBCQJ=@G7gC7XG1ZNo3&tQFX`{lHd)^lP)i#q%D1f{ zRW!8qly)Sc>LjCj<@aPy9?teEMv1UpRpr}PHoqRBV@|JwSv}{|r@mFLPJRS3dc0#J zB0~!knEae~JK0CDqHyO`r#qrKy<&tIbuJ6Xm>T%$N zNA|Wm9v^W#RLBl%J$-Hd8TQ#a;J_@-)TtwFu#&psWaIL4>5AYao`^HLZu!k<5c&@d zFn?I}{$V`(Kk2_gv$XF&nv-r?t~%vaOls3h{pdMof)5TZd%kp-SRUT_%#q%0JT$3s z2a!C$z_(Xf4^M~ZWTX+;B)XmqsefgU;{{?!Qs_w(sf9dNZc^J}P(pdRF_*t1)=68= zRS-Kdjbgi|h*4w5#RYUzo4Lp#TdSe~bPY-2p>GjmTq`^cF?+I|!nRSzhIK#WL18zo zXwVY|RZP#xYw2AWSaL6On((jxk z4QwP)cuqjz(jNTw+l_&of_EoZc^3eV}| zevu%E=!?;Em~_jnZch|)D6ae|3wTP#K!Zo{bU^$a?$iF{a1}Hi065-;ok_se+K6`g zm`p}Dgb3b8n7R05yZ%G3P*TE*1~|2qC99mK`Uj(IcIwnuHk~5JJ(Oj1f{V^FI?1)n zQd9fCofY{5&#f ze$RMR19Q%S3bl=Xv!wfBBf3wseRobzQw(qtj7RFJYa?xF<0LKPhg}J#@X(>;cPcp= z<_x}qR%fy@LM)?<9!?JposD{THqvJhZB;&Lig3*!K?TuM4H-8(!^+}u6K0047$MSj zF(-YOFO}Wv;%P#;)ugL?DLpUuXzm=$%iNS1tBj`wN0Q)EUP5NoQjVK`2I(}V&++n7 z%sPZxno7mVD0ag9)6L(!feqm!OE)N%t6o@xEV2x%q|Fv}SdRwc?vH_Ci~80bH(_KJ zjRJBD_xl+pb_zWE>tOj3slD*U0t!52hE3^FSbuwVMo}pOUABxgCGCFg9#MN#MZQfu zP2k>)`&vs-g(yzMLA6>ud-86rpbH2@iN|q0OjY^>F|q|mMw!CnbLDfCTho=m$9(_v z(#M`5P&v&0gn{tawedfF`G*VWdk69_(-2I^x<6F0Kc)Mvb9nMC-Pzm37-lF8>;&sO zK4O+%Fdh%dqt1EdNzDgiWL@op-!8(! zynUxDHu1wB-VH9{BqvX`pe6=AT7@!r37ySz2KRhPrCXRUKtn$NzTJ8Btat~qhScAp zZ?&BRA(piiTLWocvmo7MSjJfdE)h}Vc|A`HL9OJ`O`W7zx`ytoIGGqQA(^8-{+JnM zi-g2$!Rc%hOf$21x8`PwJYamr3%zp_24dsJB$U0NnyH}#7}SxRQ=BicC=r`DU?Kd; zgC7MV7?{N#GbPRxNzPm#rCGq(pHpmjh3{x~>E1342T{BGPo=jXU*I_^MijD=x%2S@ znpJ8z-2&pu=GxsFjGt6h9ChJNmkse|d@AX}ot?>eHD1~j*dEYl<_$t%TmM<@`GH>f z5BMYB=9u5Xo$r0HJ63<_R_x@Q=>;AAm+cj%vub-U78kZZGQFv`*Q2<&{e@|Z+VhLW zFWR4&K2>|}QT)2C%wlqD#&M5BSqZ5J_V+k=SY|y>eZ615ynVscKy~VJ@zeHc(-7GV zG~I!`A>;hiCi!IK)ueL#t7$Wh08H?9t_KL#&N!BoImlmPuItqqNgDL5HC%fb5B|=_?@jeM&D>Gjy+W z{(an7x&$;{r#56{u1q7l_0wK>2I3{JIAFb8fWxz!10zG3hRpJs(B)}OB|(a?=_9%< zYPsGh34o1)d$5!U-iCnREk#U27{L27;v> zCp&MevO!SH_^!I%3Vt~CcI$O^Oy0x&IPO9Z$|@{vRoDq)$I=R$8ld6=b*D1VN>fVsL5X!JxLkOV++voJF$>nNm3mPak zuo`Of_65gH_V4pZDF$4&=*R(0W%rGH?x-`qL2BB5R^kGq?kXoTgfKQ4d2T{~Yv($UNIra52@`r$rcIll>YdgiLyKZf?Bev5w%K?RFC zl#K=D_>W@_{{+i_oFb{l)fd-u1FAO(L80Y<q8?*+V_Pae3`VN8(9Qju0nazsgbt}D*CA{ ztf{$skz0#S*nCk?ekcM`8)K}?KIwWjvQul>P~{rX0F$#av~|VC0hB=zK&)Xqplu#r z*a<+@JZ5GD_IFh)4X@)-yf*SC64ZYFaHaE|Ie350cJmbM}PiXelHa1|K1kB^qlVx z<8;pZ;XiJwzKudf*Te{$nN6MmOLIZC_8<$+1CD*5uyk$7zjGcI_ zQUuH2b`#Rj)Rp4=A;dkB6pt!Dk+G$ukvtuNlGEC9Y54LlH#MPW9k`Z(houHL+U)GK z>?ztI`Dxm0e)9>D{Ku2&3#RtAE?kgC8oURQIHi&ZG)z3s-g*LPf#-!9gS%XI9}z#x z53Bt&I13_IIPqHTPcLu6*0RwHHM@6ThdInFa{4NsFZsxx-LuE3GE0Hj9EcuN!3Q*t z*Krp4h`Rkqs`)2jp?X^+@IlWD0J)-|6l}R<2%-=3+E63a_k}Kn5dS~!-aHWM zeg7Y~CMwFPw4hSPal} zhA{SJ!uO?f@5w#)+_T)@J>TEw^ZloPj4{pY{dz8s=i~W!tS`;w)>Etsjtpy$J~N|RXOGu>9MVeVGaU-p?+e&SkuTbJHhmh-kGrgrc-Rdlv0qgA&`wULN*fW5ct1vIHti~Ab?qZ3O8xY$qoWORS zg~SD?@-~Jns$$Oh9@=uS!gV!xu(8J9nala$@_mnKxTE27bu*5xS3A_Na?jJ5qxCt5g1ee28C#-2QFSjaPLv{n2NfJ(d+ zie0Iln*0L9qB!NKrTI!GwR1(@p!4EYJ4;3M@9y2Jc82;RJ3Kx!b7g7hfHG;Wk7=$* z<9}2M@$G?20oF^K3W;B|B;V@Rw-6_&3Wo(pXGBq=)lE5DDV7r%>x6`5`g~fwgK{gC8o=B{rda?yqOz`iElng-lprpJEnRYpds-CR| zYFsQyEC~;huO*gzJxKPdyGoUwoi|p zWk#_RB|pkZRb-z?;omKdcG$vf08op>I~$H4GGk(GZ^N1D?^r&XzWYOdl?SsFU_R)= zB9U)3bha>_bBE^60|Jq&F&kW2)Q(kd{$Xn(M5wX;F#P?Zx5qZ+U9n5iK%@-oG3hrI z(1+qceKlQLu6L_w44CpE@&HZph@t{2ndmeEQXxTZcw;l-`Vr+Fhq%B%u>oypZu~lc z9mbsEkG8&YrYEBxeYE3sAE4$G9O&Vr^P$h9V(@mBJOD4B`2(Zm@BPB2@czA>*aU}u zN4owfZvHdD8B{0#W^;9O_Ni?7#~PW!(f+2e8ZjomXJQX~mO&vtJUlW7C< z9~O!Hh9%pp<$FTs-ezYVZur69+SXVbPPdK%%!KNQH+NC@9x1XDSE|bx3>;PrjP%7{ zRq5zpzkr%Ra9jCdeiin+gi3gdm$ zO3$ht5u#Fdf)Td?vs^iZ)D2XK_7g#YAxr=SS5oKdj(*_(;Wz}@RhJH=F!%K}hvAN# zj=Xd$jG@8*K7!N*01c)zV-Ah0N?%)!uz;XcJ8ocrzx7k`xVbmnbeR8?ApVVl%fFb0Jt+(u!s2I{f#!RMOrd@v=f;z|D%FTzzNj7t)4(AGu3d|n#m~=}TQ2`Dt zu<9fb=cYU}JfF1G&d3bfN!3W6A?`qrHSMM$%v*Zzwv>X!&Ss=cT`DUPUKcRxJ6;7f zh628=gW}rFo{LA3l?SMhO8->yV)%eR^c;U5D%exJY5vVz=f}0T9fGHq{pNZO2V-IG z%j)FtYjr)Y#wkqN{1bfR3hApD4phc8A3PY(l8bpB&XNLzI@&UX=Joomx$zdtqOFw> zwYBYPUq!*HFH}WhfG>COHS11Zxv^=nL7ohrX0q2oQ1g7;a$&$H`e{p^l!ENT?~;u;y4_ zh!X^oY_Cd+r0!3AWiKu#omc_?+g0zYGU*xR6oV&12UbrDbY=8iUhzm&l3lr$taNI{ zIk`->@J-9*zt%)5P*ZaA1N3Lh+Ksq$D;S9zaFljA6apRt7~_!Q>4l`m9r(^Dru!o+ zFXpCp6flVO-X>tEerXAq#(>3vQQu}{;Y4-xJ!p+JhAGu8x$(=wrzjV6*Y%@lGae-w zUU8FJ*CTw-xuTR0aiF%!Rf)M(L6Jq*q?E?qQ5lDQsfx)XwYH+l%s}F<#d&1W>EqBi zP2n2e;SLik)x%A6QzElR#)W2i9|W(O0<3|=`b zZizLF%V4$8pBE+pWdv`-e2nm;6snk?U13>GE%k98D}kl|1f2TX7-L+v?ZH$a(|rb3 zv9F;Epw=s20#Q}@a3@=T6qm!n=?JQ|FY4g*(G8;87GT1Ba5-rlaNqMk<_9GbH+{ns(4e_gEu=)tDH@{6SZ z>j7y~qx0>PgIO0O{@&}L8+~tofNbp55$pqz#7}CC1$n#TvSnnMBcI-bo?#iQ=9lIK zy09MmnYkEKA4W-5Cx^M;Ie)zBr=qC53qLa|Qo{Y^EbN>Od`v8*I@yE%^^TrijTo}1 zUSN0ET*<*e?hiph>oN4X9_QIn5d<+|x7t;z z$F4_wk8S8f3nSMC-jqWm9TiH0PRwizdu!_yp|{wroIGQgC#k5@FXpAxlR28~5HQ6_ z6lO}tdwOyxDqH&M`m!otZH4p$3(3RqwhkQc#%cl8de)(p(vhbXfxGa=(Y% zPp5UzvhvJnL8#d~BWbL}N;BSF3Eqfe!Es4}J6NUNl9511qTjdMS(vF+M@qrM=}Szg zrhv?yuw`T5(>zzU9kt5XuY|mU;Z;?%#Oq=!5(a#sNUMqo?!-EahH_H*o^s^b{pOm= z$hS}?jdEU=A9h8#{t$4fCv0)BG#Evpw}yGwC3=_gf<2R#T$LWo8G-w|BNx>!9@!5J zP!U2HfRkO9uHO?bb=gJ^>(^5%lz~U}~w1AG_6!fL?Wqz!xQ5$a(1ggfH2C4mhZTeHg^* zERSpLuu`(!k4Xoog2v^UzXMA}DUW`uM)(sq_Irr0r(-$~Lpo?74L312lJA6kHZW?s zc{N!jWRHPS%T4QK%aA7qM$I=ZlP`zp8yHb;+9kR~wx5B$XnCM|K*G)@yP)NX>JqUUb~H6v;KjK6Ke2Cp71 zK`@MQLL)JYyrU75YD$-A9)n#RXtRrbZJCr2uhWUq3#ae$)YDIfXnTuT>^!?QYEs_B z>=F^IOY%P-@YqRg8RvaIfMbp0r*oD$Mb#$~UzKCm?!RI|ItlCq(nF#`1Ki9vm|*OB zJ7rX+$>+s=_9g)7R?W(;tRLEaTUKiyLdtRt`pK-XNz5p`sY){3Moj6!&QrHM2~MJP z-)7)Kjx~iVshy~H(|ITshG9Vrj{}UOzlgsQZLji`%iNSfHe-w_j3fvq4@6DYwJMZT zuq9CMaAZ-C3&G+2_?vz#Nb7l;VYtVSP=ho#V1Cq&ZShA6z~k@g`a(mrbFAjcuL%^d z6tAf-c_E$#w8fCMrqQs-wbs$b$hDTyIt_zUg@rArLNd}ZCW+$`Jx!xE8fQ)w7PK4> zu}{ZbN$fh%qeE*@b-P?x)T|geX@@aOW*kt|roC0=xs1zi7LF9OoBJ`bRzk6P^t}cu z`3C*yZ+02qL4{vs%>4R1{XTREd64_bjZxY0f-m<~p%)y^O?qCyoZB0`zzSzh!F0WC z-Ah?y#&^cJ5D6bTwSA$+M=Bu9TPf52sQjT+66qdNlBHE{08QY+ruLB9XV6NpPx+(1 z?*UbByZ6}My?gPGy@AT&nFmmFP47#EM@QLscQjc#7RLFI?h)@I@=>HNmz|NiM}a+` z(wSVU3#*Se@N+u>A3hZ|rzj4i&DJb1B?oKZ-q+STV*rk)FmDUrJ*sh4$iv=q?W=(F z5j6KA_2lg7(tAI8m%N+>d;^-?aUSOQ6RMW};LKHOJ3{H!ax7`AqW4Ly8(S6acLsoo zDPkID&xEop?BOTAIv)0b7yp>-`c$8Ewa=>*OB<4?S312R3#0WtdjD1e{eB&PkJRw} zjQ;RU@wY<8=G3wAA;2iT7qgS7*AP8#yl^fNQl7d62?V;OdFw(Ruv`%MTOy&UcYqSL zzt813P~me8Q(E=#(e=^Z7q{Tb*D~8v)VuItt}H%u2fjk8Yr@pU25j>N%f3AZR+AE& z&UG`FUw`%9pB3}|Vnj3hJ714GO1nfW!-1F1HFeM4yYRiU^4mU}uY+~EiqoMLEoPmR z#rxw`36ral9U|OR*kmJPH)dcw<`s`AN9K#nfM$K{t;Mf2Mc(%hL)VU+n8pDBziOm* zkqO_T(r&v{#Yj}VbAZZuHG)sli^X?9ws_kt%aBs-%~UWa5`ONj4F*ac)<85G%$L9- z3(ZY53=9N-+woRSMflY#I{xO{nsb;a&1BYM*j8AX5QCsQ0-5#AqLuC?Eo_p3qrl#TH53 z(^Hz?kvV(Ibi81+N3HDYOmAM9%<5F?HRy)QMLA`%jZ|ZV;$QV$u_GDvpY;{J#kz1E zzw4uzG9SZjYs91!V<*Y~ME(bleQyIBUsSvE?i?4qBFU*8dxA829|vfL5t0F>`(CX) zGTF}P*ENG=-m9HfbRE@02&pN?Gm%bI1OR=KVHh2l3!;2TCx*eW0Nw`1EgHqB>407F zue22^qy|^}onNpLrH@VRC7Ma0>8FtyOEaH=j{dRC*;Z;e6JI$X^9BPa>G^jNq)*I` zS0)rMy3mhCy;AVGktwg*7!j)vN{I95G_a%(6_`%46|cTKIR1Jyc(P;CqR^0;-#paf z@`D4+(I)}}&?8I5iU)_cIJ7D*-o@H`pnMN`eCa<`f9(@L;njNo9bF&;x8(bPE_)$| zKeD<}p9>@Im;_P7Ri|cR0;Gqf+Y276v~?fY(;4s8+RX|kdEF0d=Jf6tyaz`8kE`nj|5kL zBL4jAT<%*?`G&d*{B4vC_@ICet=(t8Hu-cQjrN@K5>XCuTKuq^&Kbp&I>H*iaG7Dj zwmYSZnb>PUx9-r`M{7N-7fP3%%wk5}k=64KVbbI|&z@YPjPCbSKDi}nJ3?_~C(&O4 zV4y2j-V3z66ScYL5P+3y1rwX$1L)7JG4b#b!ZP{Y9h z;TY}bpr{4pz;j@MVh=wQMm^n6>)TV(u*o=fQ_TDKldylePT$ku@0BXwVeCIQNZkyG zZqAaM!uz)m;Y&JG;*Y$$pu)AmdY;G6E$kib`-l>+UDzH+xZ_K*V!2qR9(I1RboKS^ zh{1c5B?9M#lHqxv&)R);2;%uEbjjB>#r36}e2ZDmwfr4mb48ra=FMCut<1eJAx-M$ zNjkj7bkpJ4Vm-rYy`Wz#>b3-Y*S!HpYp)~COELmLR3E!t)qXmwTB?0oeo%2}q|%xC zI5RP`Lov_0b0=}e2-SlrI?)+GXLD#7_l1JNOP<10F5|i=Bi8&Q9cXupR^Z;Fn8 zJdbXQt@{YbzryuKbwm$l-~`>qVY4^6vHtYI7-z-@u==_3#Tg&W{HO`bSavR!Tv)Y+ ztw}uGZ@uWw;OO_mx0;b*{rQKSO#G&JU1 z{;H;`X30b5I414MQb*VcF8W;VnbI55W7a*zC`^A96RKR438E$!-}sU-$3)nvrg*q~ zhfKiJ^9L(d_uchZSJZQ1MDEhWBN9+ysAWfIMKG}z?7FApxm{=*26nQE^VJq?#mM0Z z+N@RxZeW)5il=Yy*`TEh{$otyCcMOh@T)qGY;tu=M@Or;MA+fUj9SJ{AVmS(Ntxro z>N|bTfOw@R1Y2>FR9r6CjvW{nh&h7Hi+N!`1a{iluD8%!xKP*dEOL&o9lJlz6|cL# zef;C-S0(8lNr6Eya{8BsZqpUr6md7*!A+3luU_}>(coXv#eaUAKO6SH{WcnFv{L!LhZsHz~8%WRu1vJ zBc-ayOwj#toKu*XD~ysVQr;J zt1qaq9rZx=lvN%Hefqf8N$H1JZY&r=;4_%vkt4w!wa&@4sx+7qv~O>3P-xPCOE>66 zOGxF=3iNYIi#1k*U36Cz7cfPRJ?e+Lw+l5gw=D>u$#FGw4Cmgxef;PNdc7+^gnlgB z0iY-B7^#an`qlBKFW3zR zReXdwU#fB_-S-h{a?LP{JE;ae;g7tSC-jmzh@f7cB9%P#WLIRjZSd5AN=jdn=`CR* zLETTlb#y5G_NbcT@co)TxZ#&~#P>aQjBI+YfxXZMH>%tAtz0wy}3Z#R=|cON;>gloN*~VTdhc?q|B!A}XA(MhmE# zGFRN7NBjqKyFY%}Kr^xYmo*b1nNJZqayyGeJ=#CX78!Eb@(<62&)sG!VDM!3K3Xf% zAD@|1G>;QWdgz;Raq+bosb;aLqbsKLv0%MtIAQSxZRU2%umXkQ$Pf}`CYa7VuH1s2 zWI_qyN3K{5LCV#ITbT$?D|p|EMo~GRLl{?ycjcK;f%0Ov25$-{p!y+)#TKUG{ia_F z@I{Wazv9XDntXY(sG0)w^OScG*`s>gFNSPbsjVq8J()SyEOvWvd}MXjy?o+Q4SKRB zk-)W|#xlrt$wxggzcD}GtVv82kW>S<1-S_mN?#rB=h#qoVbZ)HQe%x(L`1p}*q%9X z1`i|*3P^iwv&4?&jewB5t#Jp_Hmt__p4!#i<|*;j(q^Ik|I4-~Q$TP3zQU(9h7usq z|GwvpZTs7%E=n2mbIMzgNnQaG@Jr1{>ds**7f7USS}2Z(-l+Veh>$6-Qg;K~)XfY= z_d?0>l&+GYSMRA(chvhKd-m6+l6Z<|KZNs?G19|xWClBAsvoKR6S<* zc}mVr&Mj5Ku&`TBRaB{G#j9GG6C3$5)MKhyX2QO!HJ4_5)!-e%6W9uf>!Cc@z-m5s?u=5DK~dqS?r1Y@C}2)tvPD_0a5mtJxAbx z&$Bx2?2EQP`^9fDXt8=RgYL_aIVR<~%)KNVZC`8cq)Y>fSs`ObekJI9WU7tqS2+N=^NjOXn@AS7Av%U1WM~lUFPG19_zq<->h2k&Smp^$TcO_)SrEaaz9S+J zU4(P$M2~+p5~7NQdBOk@n|LpgAQ$p*N~aI{b}RK%t#GD4a=G+QkN`leS@wBmlw}o~V4o)mrh9X5 z_g^|761B&-!Zm}ndY3vg>O`C5AW$3^ew?v>0Y8vkD3~^LjlKj=vjKdama-DZ|Fvik zKy5!{!3#e2xxYRVK7NTdb^iv_sd^U-Or#-d&?6Xm99yy0D6$yas8*ZQAp-N5-nZrs z1tl^evt}u~>`-eKXJSfz1F(pQ(lo_YQDu6#6XOtTYk8pwe9E`<3Ndtz5|u zOTN3b^Fwvc51s-e7dBC2mbe+j8?$bu3jza>R}XGN9ME);ev!y&D}My`VEI@1$a3E@*qEPsL}Z=vqIY7$*nt6gKxQUo9H%_4#G!U|de%aym;>3!s_a+- zMHWzWP(JE+HGH8x4_2jB!tx5tfMFZu3lmBiT0!AyY)k|$DzGt{m1PNuXd3Z|MsoBp z;XpH^h>i3rv$8>{?)fFQ3w0DaMgeqPUnu9>+TUg);EUS{4}NpTwW;U%jtu=`K^-X3 z{UW@7$A$kBKHa~8kAC_n8!gkV?WoD?ROK(qPfhcV$30DuB9$HJB+_Z=v=V8z^_L^1 zLZoXfOBc58PlN!e`b7$6y-{Ot^5CuR>O@b%0)TP%EE3kuvprKQmKoI<$Tp(>uTlkND0^5=cIsY&j-k#i-lq9p0|eB0FJ!_U|3y? z?B&4^tRVYV{}u>#L&5C@cN=VV9bBCQ<|NfF<`A7R=-wOnI;O~uyTGfw9O4sz9^ZM0 zlUmxxL}Yn(0<0@;)y-F0kOD-?mAX_gZTtV+BmG_OZu5bC&-1_;Ty*nKHX(uEkMj56 z$W86qw-)&H1Jb?Ws0ryA&LvrcNg0N%6{+z}SwG}8ZJbtuPn4}B?G*`jWkG<4x;)u& zZ%VDqk#P4l$7{YTDr3tvq)QZA!~x7X{)wU7vYn2t;YCx==0dEdOTGk^nwWY8qt>4y zt_8b}_0!_O%~^R@Bw}@34l#)4#8QAO(18kGN#=841#>)5!TVSOuP$}~qu2x7@$x`t!FWq;=tl))a-lZLM_1r{nXu0rwoE-JZu)gAqEV(tgQ zb>q1+v{mz@mfm1}oQzg&keHjFz#b2%fE4V5B-rjfT1mMJQQ}|9z9XZG7;Z+LFBbDg zSDfxaFcG+~aaANaY&c@e_^vA8#g`J%z5a-No_Fj+Z!_DNpGc?MD*#~%Yy}MURK$Ng zUr0C!*kvR49ZdMxzp7QT;4lQq9bDrd))TC!e_i?;HsdS)+Qs@r!mD<``U1SCF*@0s zS547nscL+1BAK72r>aoBA5h~krasVWD2rafkjF=_Z>+Pznb19rH0i}$z^rL5q8Zz7im!r|Cmaphlv{E@{a z1;$>Kpiy^iywjo*CI3OIvDj&A0M~g(A8uWPqzuZGLn`g^)_WJ0G4LZS5nWbhuGY96 zbGQ1z%ChD1RQXy{M+;*aH+Fk*z}Z81f&)%junMkt2lX{8a_^J5EeHUMA-}$T%!EC0 zbMfy#R};Sgc@Qjj=MA*L~zC`^UzpriMxPy!69sFY!)DdDeAfKZpG4@TWG zkzTg&AxYhCT#_}NvW8{tX(f1GorYK24-dHmPes_6n8}lQ0{@h-t~@|3kFFI8klq3P z^7_(j@;xvonjB1pT0rcbF?xAYp6XIN!CwX`570$_O6h+VGyJK4`p0i?4if(oy1&of zzTujG&8Ubw?x})~oHi>={(7OD2hYbf3ud6|&9W6xW7QQXvjwi|?%PmbV#xat6GA2t zYo3z*;a%%ARXi>?G1Uf$=iyG%v&-VcbI$+>3blT0qTZovBCiZH8ZU1wq?so{$9(1# zy0{)QeZD6`VMiG+Y5bTaW=u_K*bXP8dUBr5SB{p{c|h6@wxm}t9v(mm+VO>nE%7~N z!&XGV0H>O%8qk)mfVv%DHx=X%5x+H4{$RZ9eH44?t92$q%Y4RN?djOB@L_q!fRTXv zHF=Ux@$td)g*N;F%ABWRKgbaq{?NaENShMqPbd06 z2k!(cb<>;`J|AODd(C+8kGt}@u@<+HdAp|ih^)Ywt5M~)df)rr3P`+-8`shh;dc9M zM|0$$d`izm;$U1NVWDj{gmDf=XiBD?Dt#*1gUGnn!Z-^Chv_Bvp=`H~C>JmmJLu!C z{PVtIZov3qK&>}&?aZK`NDy*`e!Y^P_=ND08QG6!(hEa*r+Bua%LERctbtZp+wSvr zDpq1jtt1_sti0w8$McjQD-V~16Vz_Tb=%dt*SM5sDhn&?;7Y!ha={}zs%?Q1O*MCB zh*{>~;PNMbr+L*%=M3TNfC!MKH4i{?D|xFe@A3R{L~?47f? z`=W%ipKmmx6tdUBIu_yCIJ)q1L@D@|Q`fFZhT)1rAs|RcC5^18;3S78`wS*_z{EVS z`cl^5b?S_+xt@|i>$SyeUP2SH+?2_}970_x6tJcGt9Z2bc#NG7uZDVH-&jvWuXPGY z>Xg~H$Rb=u^>Qso<&SHt$~>Sh@WFT8x<0pS*H-^~wf)OWM*hMv7GnacN|7*NSAiqg zcL?hg-@uh(%|LP1pW}n1A&ODO`de}l72yex3g?;Gn%T(4orwgEDrhL4%Upx{Sok?0 z+s|(ujaaG3z3+nrUH69mS_DftK+HFW$t(ov5B4T6OMG_$_5HiM?0KffuLdS2$Q=)h z`q;2)(dQJUBrq8R6mde^h4 zxj&51+10Ekwddx34lGV&Y0h}QVPw=p6h6EQ7+D|z0a<(b8z z#SeSl-?8H)&(kYJ}+AHI(z#5#rM!v@$Z~(63jr24+8 zJ;0bJrkAmqPp{5o$y7j^w)iz46NdUt*40B@BcD$Z zKJTBeq6fKEiS?|NL}X0MvV-BL=h||X#Q|3S=~6)eyX}w2z3T2s@QmOq#7C(?H-ON8 z*VO)GFYr%FCci|d{}H9pH~0S@0ruxV6bq!bP=Adbop@Z==*i?&>&_l_+Uia2=S+xn zNsTZ8H^=10#z&%vb1S}M69Ns!9)TZ6ELXm6+Hf!AfHB9* z-Srm^adqyDD-W;OxrzhH|1ccHr1#JzY;Di~?K@S4R2=m7;pjGzTQc@exa3xm?wZLE{IaQOkR$R;=B6 z^nk|`F#7o#yNL@>w{)TrJI}r_$`uJLtke!bPl!Q#tO70$$7&sqqbJQr+l$w+ z=>;I816yWA$EfOjp+;d>RKXj2!yVh`V^* zRo9YA%E$K1Pmz$Iyab3Z$;ogWC)tIFqqibz(NmRQFrm=?Dyd*=Az_pU#Kz^AnNKDvxFn;>{qq1j~-ds+J4U~|9NA~N9#72L_%r~>? z6%><=_6)!AOLTV8auHHWL!bgL3C4|$QORr~W(McNmpokrUr0h(5xR#??ES z=O=3Lt0zsatx-?*pi#%*AA}a$^zq^vqT*Eb*Ce(?UYAbDS;a?cbt|}0vF4PQX0lYF z!ac$3M&oOkr?K`O(MIB7I+AWjbZ?gkkzUT$m!b+hB#yXLJQ_f+IuyJyZ6@!24tqE6FyfsuSeN@lHKHaQ?8wEZh7b=bnCF0ZkQh7;rr9IGNnf6(UD_0W!@#TP%`}xNG z&bRy@JR;w&=eJX^u0ZeDbYh#{>rY(tpU!jBN5-~Xb=x~jFItIrKJl;u%@@}l$xpCP zThlrQZ_cf0BeRL#7w(kwu#=*yi^{17Xd;^RxQi4z&QAr7H&RcthWL@zUmB}VlY!?4 zC(3MjZvB>)!j9zuGq)X6+$f@r7JN6w&+GMWqU>_E!`BWY=>FR%rPcGch8ga3F)G>j zNSM;_o0O;U_K5r}^X?8KD%qtk?$u=ry@FnW!Y@q)1g5rv_4dK+c^r4ADb3VuIyGrY z@5%AF0Feobgq}+U`c7~9`{N9^Y-m9P0Xyb`jT42tq!47MlgK1jyp0;kNq1TwGZx!N zhKkPnk_4^PNC_99T&QTQxTAWwmP$dl?G-3uxiy?SjzV=ViJI7YIU{N{hR*l%v;W%{ z^Uq)JPAcuvy~20>RS&D0%3oE{%l)g~m8VvXmOrifSe{?CRPI|4g=A=GLeKX#c9O?k$JJ;P1z67fZbBWbueXylKtUewp;|k+50Kr* ztZnk%eBh}}1kv429C}zP%ELtB+~ue)M&9jNiluO&tDe_+1=b?oFb-Gf!qJ5-3&$2X zxQ}vg;XX##3V((bcaWRL^gpY5RGt+u!qNye-CFzm)ae{&$R{B_lI`HO%K7AS8f zNAJbreOQTU*Z#Pw_fm%c3&8KdEF}U*C^~vlD2GQ(z{a|(_S^*)Ze8(3i0pE>2 z^|}=jU3gx11UFuw7dCZCtmBGN<7*EmjN)w-(xh3>_;a(@5`MjrW^ZQINpHTm_?slh z>KXfW=5S|?Um*2T$x!jO$XVq(AZdfpeR8_hIp4(aiOWn+`@+I$9@H?sXmTT>55H+| zyBBfp@-)S=@=7zA6J_<6UEpZC-ucbJ_ZKn$x8ud%>#ctY!ytrXodkpR4LXvIrOc#3 zDJ9ZeTA1Tp=xcxG$l(uHv;gW-;GJ_1+g$T_3lssQE@6wIqWWU()D zC(($4jHA!l3ayxfYx*VZ%E+CSnvwOi6|Xi|thiq{$b_2vW)@A*ejcT#mh~cbwkbZ- zt3X?kX-5SXQnu<%$qy9^?*<>_Y%;yE0XxVx$fm4(R zRl<`sF0YBClBp^6_hVomFPPNE)=YIvUAyr*hTj6@AV*dZ%}jR|BoZrE5uE z-KIhkfyagXQ@Q%{*Z0ek_m37{o3g4ONs4>y$UVq;-t(-Lyp^oNyuz%Byos#Wc(1Vz z@(!{>cpscju zC0JkZzF;(QX||nsbNZF!Ys9O=uVr4n|9W;dxyY7A+TvnIHVt}{G!Y`v#q(mZw2CC6 zykq;iVTq8Fd<|6K#$r5AP9-`%JUEKp8jX8Hmz_S~)p5#lbmWSLw|G781DwGAGo=F0 z`J(uIH2B3k>QA#L@&*`<7>=fyg_1(+96T!AMCQ`Ez3+tywhS=ZC$H}GNv#Cx;m2MJK;R22@u!`I4!t~ zg|4ANu9&14VtK*q3ar>tZGQ2{|FUSi(I3VA)E|9+-~#+ecT3?Wb{ZI)hS{n*s*kRj zkX@Pat&Cpx_=%89oBP-?dAr) z#KRAZ-k)D9wXJJP@FkVq)>8biZ#Gh&Z)WyHWPU4*&EBa|{%PHH-DlUu8BcENSv*3* zO<5kYT>hj#`Ql5L0^-vUdRzwAz|fm~Ay5dLCOelE-qt$hqIT?l3QaL8rv!RB=N|eK z>C|wm0D&(Kwh0t^|woUH{pWuUzK%`v>PmZlx%1pgm`us8YCtPzuyyu%FHwT*v$p4KQ-_C^V zXiik11{cb+WOoW5$*9Ytlk7YL+-+yfO3**f97?uMb&3&^+Sh)rnf&~JQ1h~pKflN0 zUj;J$T#8K+BuJ_rHTrlVRwA$>oP|<2w(4TE-V?eqQID8+2~iya-w|;&NQnmS9gQ0m z?YjT+Gua=h_K-b?gJx$oE9}d(Zi=HLL$o7qjiZ z-^Emol}A@~mKRp7ls~AdDHmyq9VhQvM$YdOvw!iD(Up}KX@{APO)ltphO^pV7EBOvLP%Hp{gYuvsK$=$J7u9Z7G!tk9^)H(xZB#l-L6TjCv5 zI8j+@mu;ri8Ik6CPhcE;_enELJ=5e_IZvTNVtZ2C(1KKV+-?GFTAhNN_}ChXoTv}f zDoI3hUMl>;M=Z>A$ES&2q#2{4@iy$Ko=C;Wa=j;(aU#$8k~3nI#$M9(!ZZX4r8#e) zu$)D5t|6x7f?i|1E5MNgP{-%TBc0xv$tT%=pf_UdGS>tH1p?xHOaf|Iiy-d2?yL-6 z1}g_I2df`1ijANN-z^u5h0!$!F7|(_a`qX4NU@n}7Dr&^9b~69`hOh2_P15p`al9Y zSZ^Qg-Ci7tRiGmWt`GG5E;RUGzjOdVi8mWcltPDW8+1|(YwawvlW+{k-OGgaR%UX;>mG2Qk)GzPnWEfVDtvR>Pmi%9qy-6XT#lGpn4J1G}#5<_FWShFOt+2Be%SpjjGvB%QnQ&|<1=OP!%(nL|(+Qcvy z)0ff`V6ZK1Vi?DGSmcTq$E>B4R)$;XG!Ek~&a7_J(#e6QZgES0*6Vz3CP!tY^y}A+ zE-z;wykYgaUwU=3229f% zV_u;7f3U~Q#*g%Ro&GFidVQ_{Bq@EYjn>&!laAnBX17o$T`V4_5V-^%801EJXe8<4 zZ6^9YWg3`^^F_gY)E~X?0D9D2HclD{kRFiCyix)!u zvfz2lN7M1r7hO-9hM3c0*8$Goei+;KW-Z9ABbP-F3eN1g?6h92;sj!IvK^dE|b(>&n3p8#UjA*+2Wa53!jOmlnR_B{0KVcp}U%o%u^=&%vKiZ{lg4+R{ zDb%X61^VFVgDnq^J>XD1s=7t>m?}rj(V8ta$7(o4j*4s%IVQr9ax_IGg*^p&gYAaM z4fY$*&upJXKC^#@?qS;_vWI;S^alm=V9Cx!S^ONnEBxGVGWk3LHm)hw@|mx`7f$4*{u?cl*2gLyp9 z`GGkN3ShXYEnd{j&S^4)P$y5US*KXJ51_3KiMW~bG~fVoQ%mtO1C*K35o4O_E`BLS z#=Q5TW(M|V31~$)4UbB9Mrh@bp+RaTmElLwjh1#&jHq`>G_q5{?kreTj-Kz#E0u86 zfg6hlo$@k_3>p{!i;Gw-gc4wAR3LI#TLHj&uHqv`Htfj_x@XhekJRPba-|tyAGd`U z3fZpErSzvLd#_9xJi8@6Wyl#K@xU|9)_uNUsy?);p**8%(5ELrF`&f9BVg5sHQ=7l z`2Z*jN`%055D6E+iZ~vn-x??=pAFc{A|+y~QG8G?8hgy)2S+&FW+10LplaOb4DanN zy&A;=Sg7NPY5RV?0ZhMUGAHW6rX$}}^8Tri{L|I_{b%eBc7{pC?A3m|=!K*iEM z;Nme6+CxPxQ~?-(>>=Qg7KkJ_?AQg8X&JU78aoy{Mb?BH0U+JE zm^xgu>wS_werBUMQDF>yzE+sBg8`sFYBe~miMp%AG2F|QSSg_yvOY#UO6+^4`lDZq z0OzJTBglB)Z`AM1rGD=29*e-+w7-SnUq8*CU-)aG^OqBoKaw|5+oIK?s&AB)_G3+rdFNE*-!J`*_c5p#N0>o%UK%lB zc}`;_KwJYWj;kf%Zs|JMNS&G(^6T1tDXm`cp~fLyY4NM63bHPuy6LaF-o0sfT!EIj zdAabKe)3BL0Mvbo3?MoAgNaJ|==Bk-&3&jsEm~nqTLozSvR>(l#Mql6;uS9Dh{9a5 z6VX$24CC(M<9$S>eA`d`Wp;7Wo}cnxKj^B@b3cSz%=|z9!EBiKZ z{(eU$=yQvId3%sj^*Nf|%XuLxO|=h`-xG;@*RwJ<>u_bhAXQ@AdR=u8ziKsKAbzt; znPg2m2TH#CBr}F~N0id4QrAYsAe$09LWU3nc@sKi#Q` z_2zx4SF&?~)!noyYbePqkFp#WsE?Tm4>IU%CWA0N3twK2tCNqy#r2UPQMs4v+wVMu zb*;d*H%6YH)VPJqUin&By}ooNefV0ygwOvYy@5rzZ31Ok;ADC@mBge0xk?G^I z6RpnvaSao#9#2gcH*k`;^I!M~FbL`xET;lJGBl7L0NsXywPuvuQX@^Ory60$PEEIR zg1lBd^+Bk6zT}RT8dU99iuixJDF0IA{rOg44E&9MT%+&r{nv~f{%yE~!<(bXTVAM< z25vyuQ!hsu=36JA2Q74N>SFe%Qfce@jpJqP(;%VH3?@3?((a}AC)Jy+wXTou|5{yU zFW`D+#g;f(Mbd!6?%<2p5eu(tylat#;aNt(V7_oPdmGcgfE*|_3;uvKbci( zOCbWxII{oSe9x+d>^@+v@yvA0BQ@^sW4~i%#vKCDNo*vVA{yywI1&ml>Jl(SfaL%f z6U>V}Ng8$oWI+Po(_G1Y9De=NvU+aVw6C+pZ%x+WZVny7ZB~h!@viSF><EfHWefP<@8kmrX>o2$a(rv45L2858By#GdAc%Pm((6%6iITHbr>{s*g+< zX;f%T&tz(gb{#utVUU2HeuTt}M>Phb08Bh>Jpg(-n3T2~eoRwI>%dxd`|v*DQU_PP zwCq82tv{i1)}OmX0(!V3b2x`JLQ64n7EEy>KVFBQ7L&}0ihFfEYWLIFbKz!Fio>l} z7PG?zEJm8up?en3Pkc3)_^Mqr6XbgAL{8MiJ3XaEbO4f{AZ~dittw@zVO90d0LtHQ z*MCq`xMEj|&YE0zu()V()BHyZtoa3t>*jhE7;{aFTjs_Vc=K}>7UsGZPUadGHWo(a zI15$t8y5QJt`3PFsmmnzibI9=NRq|I~_pc2`^`Z8zb8XX$R@ zbq$x2mr^(_B{69i&?J$h7Pz!rU|;Nk!4V3^Ss((?4#*T3qvs;8Z`6Zt$z4h=9MCY$ z!tV5}u!L}w+_KbAq*?U~Kd6932ZW#sD$Hj%8;;anJybHIW1^6?^(lymym4~yPx1s< z)a{sAlt~{Mu3NG`)Lj1mRFayd&$+inrQI#nJB1s+jU7Yj87Y?E3$1|I*~&K5rY}4z zGp?Z6wK+>RlYd~qMkpL0?y#leuq#VyN-gtkjb9BfEmB=00pG-!D7!Ref*3d$z{82dp5 zl`1lXuKe5=Zwg!A?#lO=^lx9XDK7n~Ch2=9{lAM_X@Ppo&3ol$*Ob9%eOuckPg+NE z8I}B;ksm8dB|FMQZXKr5P+RC;Zn6`4189$!x!50z{rpIMOG|1JLbR3Ivi16mX0zMG zDS-8I=_pQk%ZrG@IrM>rFAW8TE0Z5xa&* zyZ|o(AX9L7q~&zF;rhoJhk3%@Ux5PuXoK~QxcBEO{GTRv-=k&=z%~y2U%)mvGRRGP zU%a@?2}YxOC6Ys*5fNQYt0t26FV=RjgG(mqtB+4ZTsz0u&Zaa~>uf9Fvd|4)0@9oOX9wOdgsAW%U@0kIB1h9Jrk16UQ288pa{5tS;khm5d` zHPWb&Dl!xZ3Q7cImc4=yf;d17dm17lI}suf2z(FPk`Mu*?Q8A(z5eAdzlUd>`<&}s zXWZvjy;J2qTcy(kXdZ_uAyIE1u!23lb}^MezzroNnwa)k$E>>1X{-Z#k=7FSZGCZ| zw4q0XNd#YlPb{pBt6UmLIgZ~Az1si0usW?hED`PYjaB~Cvzs%|f%UU0)Zz(QE2`_j zJ#ctn-GB~Av?-=3v`M%rqG^-LuPTBnH(*;xKLRs%30QoP4Ug8U8gUc{C>FMvbgJtf z_DN7Y!emt?PbEv5xD`kA;UZDkR`QvbDcIH^FCGB9*BXc!uvQ!0BK`Oo6N*6FYJN*O z8sS|u5aN8?FK&?K2Q^SV`Zx9Gz<3!=^nSpCz!d-# z8YjdC087aZ#rhs%Pqqt0{L!)NHBRghY`5^sm7GC8e^tp7mcfR?C&v)ju{t3!fxU8pB>_ zS875Gfe;yDC8xj%G5FGO|e>i>yE#GfFHe^B_B z+w@^ccbGwyp?ipaAu|Fnh3)U}v8-1%bHB+NI+hfD(9fQt`VH_WK)H9a1c1X{T5h-0 zgt?KQ(EZ?6pw*)$!(yz58gwZbJp{A@M5#WkA_6;_oM&*A$Add)_@0?ezB_9J@ASMP zb_0{%M`u${68j}Vy^X^OA>*gKetPjLv{Ir%d`5GxzUo9BWO8Srr+Xhz`mCna(fYmW zUw~Du8YE@H9N{@0ogIOSHR6dNRc#=p0i3LAL?+ewbKSSX8*Ge00L=%-bzprWPA032 z5c(Ad>L*SAwsglNNoS6cn+V}8h(^`!;!~k7f z@HmJB2v~P%)#fY+4NFvQ9#7assk;f2azag0!X5FLhS?gKyAr?+K3RWa+K=$(@`M1V zAGj^MOGSR0yuwZydC<-+^1F6Q$*b-Zmsi>;E3dwDv%LIHN%=iH#pD&`ckEP?-@0?R zy!6h!@)A3h<>hv2WPG2#Gh=(YO2)Qyg$$VtQ2LgPUFlL8s_Ehx^gb@hj6JtQuLw-9 z8L-RD_SyKOdDm<8=h`iD=n?gHW128KW(cTGa|{NW#Ack&DTV@6KGxVJDZF}Yq6gFG zU%VaT)VL9q1Y{E3Q0S1rEG;&0h4akpDkZK??4%+?vJ>Lm^Yyf7@0|UL`XQLHjPSil zJ{H`5g=kbkU~MYUbY&n@jW;Onx)$z{O=-{l z%>xbwnt4MvT{Ve?z1V}QW(T+Pg4HnYCJCqFnVIe`~2sBI0wyUdA`XB+AI(h%g3al<7f<=or zZS_^LtE^V~Mf@t)U}~g8UC&C*5xFeG+YH1zIHPr_M2+)U>YqaZacqYf@`c5A^H{+w#++ZNd>ie?@Et4{ADZU(Z=E`OlRF63a<& zRCV*C&St)`sJ9Mn4F|F{(}EEYcPXc26h8tN-6=c_jfFq># zwHvFQVbed|yIqyfeUriFWDz&?h#J7^d|)rSc~HjzcAn+Ib)P3v$4^T35G-lrn_~~` zD(-v!Vz)6|c_=w0vToz;!`Uf&_csR|H;MH;>e9ys_K)oZrYLT>{TP8uiyaN)=QhxX zo%+!Jurg))vr+3tl=|-bm)9Ar(_Y89PIn#mmBUxoUD3J1bw&FM=M~*6+FaUmfuDZ!RPQPKQ-h~$PxYU2JO#^qBcmt7E@L3WCZjK-E5rTZ@Pl;^bRKX$ z(0;)A;E&B1Iu2YGkdear2%v}5qPSB>urR~tsy}eJka-gA$DWJLj5#1 zbIO#Znb)3}_#{{F$#+n$K5A!uPwMz9F>0HCuFq3yL99s#xNkC_=gD+(OOJ2Nq_l)+ zqg)5yCTXDO`%Q4+^pvvimOAKEL$EpTkpPWcliZnO9vZK%mc}3oS9vvNt*U#3u{Uea zIP;;XMvW7-FQFam`+DnImr&vCTt=2Ewk zk~AWMu9k&{BXRc(yFyphjM4%6|A5X2&_uzo$z=AHIxY3K zf`QfxaS)(^|9#TsC^y(+tPXbJxcL>Qz5Uo%myTXC3{~4-Kidhx2lS%FxJqg5$?wA4 z+K2lsBvrzm&^W>HgqV(GpkIt0Q0D{tFUEx6+h^_-Rq)6A=pPO;j=WXJ1ySd`M{<95 zK`t9`r7qWldH%MRtUv3Tf&F9n&rw<}RYdUIW~W|v-yCM>et-fKz3TKJb?lx4Ch_?7 z9f%J|m0LHCaenqyh)V9U8k1Wu>tLAdE(pa;Mt4nuo8>g7)E5cXNE?cmF<+ll@Sy*u zhIdGabjrAqT0-Gg7n`os(sqRJsf582w)YSp&}M$p zn;qO8F?{J65mQIm=g~Rzu=D`p-$Giex>kQco5cx`FoQm|WpA9WcysCkkZS*^Ng~96 zMNOgJ8x{xD3hup&sqQp1^8wOX1u4g&b>;Y(M8CIcQ_7DI;PWq_p+=L%jc>#v>|xj4 zy55GbkL|y;yWrsccWJL}S0$y9wngFmGwjke{yepfS(`rx5GqduD7P<1wXdtT(N-hP+4G2nbU_URp1!v6exF zyko0}^xGoxG)Vip{!MT?XXPufCC!AAQNHL4%(}2f;s{JiLS2rWDANy>Iei5pD06q?N#Pr&<{llf21&nrk^*!9R~Se(o+fdggqg@3YmXoX&WD7h)DJ7a|(# zXZE0fU?e~~cuEm(fRt{}$4Xq%JKdfynmJ~rK#)Ad91t@v$g+*|FXiHauC(0GM4jwe z8pTq=)WR7FllYKs+a}oe@cmP_FQA8wYT^+F$mA*wli0BtbN`{4?Z1Hi*Cb?4AJtb={9<(P zPuGFy{)q1Om&*(mDH<6(Ow?2Lh9zlB0fDsr|)O*G#=uOW!MHH>j8_FrT6XN^7^eL>jH?^ZugnQ28Ij!%`y8#{CkxMw1PVG$+dG z%=>AWy5qHpJ^|0NAVeKQu9(U4k?}%1VB1087n46gA+oQ+HLI7;pd=&1Rs9ZOe0`NzkXJrt8aD+ zR-&b06Afvs54-eH%LsD<`(xbwO!d`z4ygq-9d+yEX-{+tWq;+;>1?M}WP222_f+ZUF{yGGPeZbLNC73=BLulBk&@%95ZxA%;CX@j7~O9(QM5^ABu>M^ho+zqrfW>kRV&CJn7$ zlOYbOpeNt{7+6R5aG$YXZ6j*h$57zAXu<1(LW1FfqJq~1zY`1-+$b0-C@dHuxGD12 zNWsV(ks^`TBX33WN1`IvN8XI&i;Rinjf{#Eh>SJ;)-=*|gK4xWkLfMba8ps!Yo_0s zhM8_O4K)=ujWFHR^lOt~(~TyPJaJdYmjze~LU@(3xD&gBwgaa_@*TP0>aDdqXiYN> zcCiJNK&AWrQT1*IvSl8hE^utmO``QZ>}#zrC>VBs?yn$=>P+hhIiI5_iyS@{2zD3j zm`RxyZ5vCbJ$~C0MlJEsxc`op7BJwY9&oH(E}tRC_K#D>U9%Hx=BUh)70y4M2U(Eq zgc#T-%SBS;E{fh_AA~f-I>V&;b%9~F0eg;?L4L@n3VV~4A3N53qKEg_oMUMd;G{+r zAm5D@62SO6>B%sXyRS_r)xR!`R2NI5mZLL)n%74u;JJ(elm4z8RlTY$R+@)OONxnr=*m+}o8_=kH+8?0}oLD6Wvb>*&hPKcQ-K9Rlh2^TtrvZ29@K5tE zVtVKKTh$oIE`3$9%JERn|G>Z?7JD9hmVTao7GWM?mMESmmd0(VoE8yz>aGV~;;{Nb z?{n^9*)zZOTz;8vYSNynzW!KlNlQ;dpS;Lm#DuZO-U+29Bekot_(9>G*IM=cuv7?G zBhd-+JO@|m?o08)1I_(ngOI7)Ez{6?-`3bf^uWPa8V`n&Wz2g#lZHau*5~bZHF-IN zRSWXv9TOYk2K@@#Niysrlx{_6v4n`_uzGIuT2Ac0U%A!ixpXgJ!Xj(ueK($gKWEtiQ5q`$A3zKn2=mLjLxXh=#&3Ar!DFsebShvYr_B z$jIc~k)Prw&qhb_0He3W*&(OR9Fnaj#X-dy)3<$S@Ek22_qV5^z?Q$WQInb)?REbv39)ko;%?IBkvj#vRx*nw@A zYX%|P_W=Va^C3V#?&@%l<2r2m>;?sG7tmvsW66y(Ge&9t!1f3Zf<+lHmZR2v!vgY} zZ|QVx`fCn`Uea+>VDxFs3(e$>{u9$$8JoVD7nuRoncy>V(;2Ul;C4+Q#p&%16qGJ& z5qc}bc*200Mo*{#C8>MrhG-P4c!;N9Oc^8xy5~kJ77blHd6elkv;Je{=(#AsGQ2O{ zh_!yNMJ(&%fb3qxKNQXWRIi(Ojf(J z0xV#XOQe(N9`?PCT*}tgdoHGo~&ve^Gy9QTKRG7PTxzeCxJ~KI6l*KJASvm$Wtq(ntWZ*9EO>6F@ z-(T{^Xj}k0l2NkhRN_z|pW#Iobc#o6+fs;y$(QPj&&*Jnnkjb%3}R9f z9u`yQ6OBEKQH7&5?yGO@&Rocl|I=`=c*U14$GJ7p-V35te7@=(qMvuJV%HK(jlfPz zx&G1+YMxvv`MA5G4)Qjy^FfY47Bc$DIonY%n?ZpESH`3(C1AsbSRm`wVysZx`_^#F zw<*IRz!sQ}{y2@XktcQHk`k(ujFP})s*9&T{KP^+bVOJYk2S!5{i9PeJ)0-hTiVgqu0LM~;NU}`0A zh1*&9_{Tg+!~nk@xigr`23Gqhruc-r{*!jKEJyXFlmgtP`k*{pG3QX^+ZV*SwYz+K`wx{3wrV8 zm@OT+mhCm>6y!g@S7XswdAZxh>DFA=SCL8`wm_)$!M7UbM7?e}`f zi587_Aqs=r04&W)arKrWNJjZ2u`YOa!vbV$K>|Df1s1%7+2{TV0RxQ?BcEZj^tqR} zu-QTVJdF}g-?T;MNv4ZsWOI*dlJ^&6`&>ES5cpe8iA7pkzb@PH#wo9k1{JS>af{cl z`#j_xcbm)pHg@}FUO{?*QSl7s{`8qZ4VY!1nWF?o=YMf6FfGntjsKCNUo%N}4-7rd zwCKEX;YucyH%3;ZBEhk~->fbds;%Qr^%|E^>JYAwXfdA6!pzy%0?u`=KK4;8wNOmG z957uuPy5UpjTwV2I-vuk^t)_zPPBaUL;M5$h0wTASpf{x0bdSacWkw%hLC)6mgkV3&cXrOeP zAoi~E5+7o3i^-F4aqcR?(t=odxYvs6fJ9*1$Y)<>VBeMg*UV{KGz(Rm_+Elei9;If zU@ zaqS^uGvZFrNdzHiJ>pu>5kzf}JR&2=6+sSSLm+~*5miBwh(v^KP%q-UpqmJ@pk~CL zpnQaP&;(*l5FDWyRDlo+x`#N8=nmpTgasW#)CVadvV%Mjlpsz7GDsisEXbaxac!!u zMQq+?7wfKs(r|1;DOE#lQuh_yMc1PF?OM74m6l`2fC#*d6#Cr z3Cu2LvR6dZ1Y*`0ec;!#ql3IAM@sF>@b@5G0uIaQhWcQQbglT)FErmX(tXYnHeGiB zvXKE}7P|w(C4U-*=D5QLPb!PM<0+(<) zpHnNjz%$nWR5L~YZMjen;mHZj>F~bkOKxTvNo)o*NEd#v-aev2!cimku!rLKSU^BR zmBg*a(W0q1pJ(lIEdTNVF<4Ltq;(^WEpc#pVSenfxee`9I37|5gnCGV{b9uuBsSZU#zS;a5YEKO$>Az0*<|J)!AiJ zA5h?z5sx3Xx-)D$;U%d;yX(Ul1&qpAg3d8uCjF}y6$}HmugpKrE!J%QeC(e|`Y5J9 z8@0LB``Qk3K1U$es1?}XqN1FuoJRDX9P7(290dEE=b13e4w-by)@W~pAMJWNCim95 z2pVvtIN)gN%w4M2bY?+Y1XOJ3o3@*I(k@|eT@`8pqCBM&p% zpQj$}-!e?_1%b3_x~B=XiD{%d)u*W~IlUq!7B(6Eb~(WKl1bnFV~3o9O6OR1@ehZT)8|kwQ&t14a%Mw_Bv}&SdsFvE^8D$x;Xbox?r-*_04gkM@9@ zm>gtsE9O`%0csq3ax59UF=#KZ*P0=NHr_mCS7_ICDGP#?g!SV)4@PgNHNuanup(;EuC9=iK2`opD0I!^w6_<#9 z5syl^iYQExeEj9XE=s8|LYc)`tb?m4ROKd2*+t4#)g|G@1&P0WwBo1tuL4eUw!@C0 z-;CJ|*umBDvr_>NM(Ni_=(c#~=Mi{-rtgdBI5sdcXn>dYOAclH-~w)VxgiVl1L-FI z%H{Xn&Gew}W3^+Il^>W<0sg15VL8}miWIrf+|q(W zojUiWOQ6M0@YKe3D@SSfn?v^B=hYo~fN)`XB9~P2T7o)(nrf9`^`K?8V8)Mi{XQE< zVu-CRDo@Te@MRG8=b&I7ZdOrkkPu8JLoI!4#_n`!GVFxcDex)h6VOwEFZXqwcxl*$ zC=ErRR|WHeSy9>|Y@jHZEXl76UV0f3!6V0dRoseAL|25n=oV~;%NDZFOC&ZbD3`~X zwL?2vuSi%WOl6}A#I`JSd2=FnucRk#ISHuQ<;|C8So_li+jGE%tdi8)T%dpL-kVn& zZnfpuLGMfoeG_n04SYN>qpiWOW9HzqbzjEDK-y7STsD zgdO#hI@=ki2eR!$EC3bDeTl_kadBd^+!dK`*K7ZwEcdKki$*ymrcMex!R0qowTh&%K2YK!K zLsFltc$tJSy78Ma3m*_cH|;-|%u@Ve(QFqOGx0EoDo}-+91ic}@Y@jKH0al?v8jhQ zMfO5N7Ty=ufz(aIqC59g*68x0sPCsGgqbmOE(T}{*u?!$Z5aXv3XXPXkf#eNA!|Ko={|w7 zIHTi%aWBBKFKvjlTbXw0yZjIJSIs1;2WP1tbs9gf6qKIdl5S zbQk(+GEmtC-0wr}H@hhll<-pdxhF$9y!gXW4eTBK=qyzSH%?HW&@&`p+A5cVh$9?fq;h#_sa>^Pu)Y1%+9j zqy)kUM0{@2WL>w<1uDW{w&TfYx6};d2MbxQmo~l|G)ix zzgr-+tVs}7;{A0Og!ZmrI>taG2`cv(JT#eej$9)EbUt^c4HeGLOE@v(fq=^W&$L&v zL4Q`Z!06vN3XMYSqrLlSbg+fy?Q*?UwLeSbFfb3^X?l2N2d8zk3X%r^xWS32Qj!UhD(?@-Ynhuhk792&ri-ZdUN>{u`KWT$zk)r(y{L< zP|hZ~l4n~d3Q`I%C88sR0^=D}H(!d1hP^uG4$tegI?;vkK54K1-%ZB@EM-B>0gTjj zJ6F5g`Yn10FwM*>!}~;m5yZd)m>feZ^6?L#s{1J&o()u%<{_VU#aCC)S1P}wSEkF0$^LTd#0RpyGBULoN4{jB$p)MQst5rKSh0Zx zCa28QyN%9+^QQy!)bj(Ar`scTsRL8p-Z>AC^xQEZGv&-at#ZpKXS}~;@ktz28LJtn zII{zzt1v(kHAFtkp<3D&!g;c;{#_SKk%*{O<~-&stvt$Ogj=0yR-s(f>rEA{`84h@W2%kVVX;&+Mc{F_%l`3UnrIs4dBEB<%Dqcg zEVbP(ZwN8>Sbjhh_^Z!yptzsaKF zTCbZXo!+%YF*KAd#za0K!m`CdU*3Ot#8w@T&wdy&8WMQIuyIGd`f2S}VcI!+iV*ZE zX|%t7a%Awy_8g0W1498s5%sj5OlM*jLzMQ#=_at(m-ac@K5s{h>~;HSAf9fU1ND*) za5|_XW@xPCZ0w<#FsOMvWw^eZKSnl(=X!uAR~n_>@0*T&Z)58xU2G^NlT)zA&|4`2fh%fcH_fTI+n+1U-Ay~0mOy1qFDM~kac4Bb^DNOgiL zLk~J~OBjpZi@cvB_aFEC|7y<$wTP0buqGq%7;4L*e&GzB7+GUj!S%2cTKxzu^lK4t zL~Q4S4$R)fzE)gJoHb!vf_TE31c@`N&xoH{b4KFz z>eu40*SwbCU(GMhzlL8Te08{ZxL7!=@iybN#$v{-4ci*lHi$K_Ds7wX`ch&|)jpdU zd^Qs;$FON%F+GL5amuMRn~(a|Br752{GjIU33n%_G^@$;IhKQQdG5Y%_uMdc2R5O0 zvC@h-CC7llNw^AE8%l@f|MyL(Ks>1mINtW7gS!3gob~?x4<=4^IP1guTE~)WUgYa3 z<+~N`uk8&U-mJ=}k>oTyD>z_`C1YQ}oDzJZz)mMf3#k%au^FP>`43v~5~jl27gTs6 zAW8TK@pqlelpghXmA?`JqV_M8Cap2(So2sickM-;@a34DYw zukxClZ8>XmZrW?q3j6n-%QecqLwR*Epbct0JCv(2F*@x&rbk99sL$@Q(aaMoVcO*7 z%#!i3$K1({wG)F|y91`<3uu_=az~+vhM4+E-hXLq$idjzxR^I(aJUR=z@$vrcwYai z%NCt}dobHKps2hzN{$t?c9uNu2B?`>qTRT7eU{-XdThA%s z?=P57qwl|491rKEBcy{8<>uQ0vli3+{a;J!T!%Am8KU3y6D;EWcQDBzj&u-8k_}I$ z`GL(0kHY$#{raBx<`3>OE(_hl>!<cur~PAwQNVOUirIe2RTQ)Y_}nM9d~p6Cj0l~iXN?2M51 z;CalQUHB_78<`Y#&iSup$p)EN{KBurnDVe-)ARp?Ud;Kz_w2I#(C1*6bv5T+rRv@| zP_v~Q1avUW9j8;NrQz}}qUdt>#ZKD<)UM7XtN7OBF--+RJTC_NEUl9}sqtb1#$@Jb z`*5I9nyc$QgUgoHI_?GWKF0Rur z(i_-1Y*y(g_Dbnf?1Rz)Y;u#j(BkogdILAIU}w$8J*@l z^RBssH}6Fk9-Le=aBp0hmgh5gX(sPri1N2neqT+E-Int*s?qW}hC@+MFtJR6yAE$Kj{g152pPT!M7+8Hh^Rl_Cw``gQ&cAIRPu%qT{d>vJU}?i-PA0ISX{y7MYti!_vqBgr9N2@DQO* z0>+B!l721Y4@lm`%ViPBG0_*;^+%R56|>vyO!gW8^+_CJ^jpgH}rUE;A_~uG%AL3 ze~xX{AgVc}5D>MtTwsmU^bc8JjhB=yT}2p#vrK{0HS9Ght8{VI`a=mBp0MC!-~YJe zr!2kBLb4rPPSLp%vl2v7hVkCYCUq^>15)2?*s6|f8ja}1#5{cM@FXXPq~NK#W61MX zIUa1bIu zRp62lsZ+^wIZS+xI|(lr*4l8@LFAZ9fvX;&3FitY3QKG-aELZCZBWT~(IM91Y~gre zn+??t(Z^H@T@46rIB)of@DmOJ1z8!3Izjm}k`W5BjuyswMe?3&c62|+9qYP2L&FOf z$Kv0;>-X%pKS$HQe=>Tcpm%p}Ml*GiHriPYO`v2&MzkAVuFPGd>@23S)tWXf8lBKD z@1-;()z+Sec5x<_;An7GA#Q$AJCFtJF8M4W14o2Q2!Z)gb|6bwLPi|ffsl_IfeQ%9 z@mtvyS-|d*?FiYpez>xbGk=F&ktGaGb~<^QSd5#5a|>YR@Q@* zV}~l0NcpvoCy*Tpg}5{&i`uHck3$4T=R zMZC@1WLr*LJkt3J6x(bUy*&h$M|L1KmD_w5^VozxyCte1`R&KUA?7 z328sEqD&VV!I7q5wWFv3R!llXd{$bvo0~6;vV`^QY8#|A*siaUuP!@5Jrs!(u<=C{SgpBnO zg16tQ{S1gMnqkEjWC1H##udq$j+|ct+sg?fWo>PKQ7h?LhZ#}m7!yH-=Ln(%e`(NE z4!qK-6ytRtP%&l!t(09X?Z_BbVwpmx+hfB8bnm90&-CDAk(L~Vik@-w&2iX`QZlJ5@dxV zUZuSwFW$w5m|E73^kpAY8nSPL!fumK5bog0;aWl={G#?CD_9))M?xYF54RDL7OLS# z*@K|4JLFS@d$=cX6QMMIEBhiVSUmX*AqCe8_YxZBH&*JfFM^KWCZ8n4<0|3DkYM&$ zC3R`Pj`29sX<~9&Bhp!@lfT5?4{EA*vz+&%g{6mUbS+(g$}=P7QYiC;WBv^ouYE@7 z?eU;srUa1zdsArCwdnEo(YA-UhWbETlz(+H1EwY>?pjuE%^ zUacWi{rtB_kng{pNdc3Em?PK^$~tEN^1J&)T==>AVOCo#*+D z%eB2PCf5307AD(T$Kih^Wn~niax@#Aumwnxd|4>+S;K=6O*A3AN)Rd~#ko}#S-Jl9 zt_c1Q4uoz>^XMLfYn%6AX12JX|6#hPY5l_fVU7@9`b;h)Twwk;GA{PJD5_I0uy zplYSG^_P{zRXJzW)dC>{J}tFR3uEjMdVx0^eyOz;BuEN|j!%gQ6BbTg4B0PXR15@h zPJ@=tfzT~&-jef2pE_3l3E9s=V_@lLhQ^H0`)+20w>Unyw6F;x5Q`)_j0oAQd4igo zs8nCSTT`J|9Mj%fDZf$+>1oSDGz9p1jAW^onw}7ZE=s4^F8Ad?hLg8p3umH;T!C8fa5O1 zBZR()L{`RwlYcSkMX*hedfuFnn-~YV0=Vf4bbmuCRJ5_eH0mIFg8Nb<&&@;bU1RIO z)>m)fyO3`%RXXh*$>E{ zIf50q97T*(id+v89^sC_Y4 z+B5a7tDu5td} zrWM86PEqg#ae~4}wspBUK%PwSV)%)WGN7z=v@tYeee|i0!K@*{NWqwk75O)R6GVl# zP(IWw7(}*`gx+$OfgW2emuSr`!znH>$A74PvgErk@w=CtuNr<#e7{jLUb($roFTio=yWVnzGZ)t;fnlk!l>iitl6x@J+etQ0tkpuaPVqtcqN+A}>_3Tulii z++*VT$J zg?n4J2Fbx8peQSA@ggtFb&gE&O`jyJb+dP+xI23Ky@Slir_^WL%Rg>vdrZNP2(<6a zKa(PFbD&z6I6+i(bQmvJP@2jhp>at2<_Q}Oq1cLNc-8Nse4n_3_$!0W(L{H1!aLkX z_+DWzz9FYJNM5chlsH|+f@J03Ruq*5y?|wrOo`+&UZeyESP>-)!kgB@a!3}$i82nP z0Ee8Sm2A-qST^Z6ky0j%ROWD2?2s+O!*bIz$yP*K87q>TW0Rt~>;pT$qvKg*Gr|Z? z04^sCgm0QMzL{D~}Q+iA0d4OPBpKLgE<)Nh~Oy*&kERE=*(T zn93}4x^G%$EI!M&ywRIJYf4>LC_+hA+M**b&gC>QsZ1_N`G!VrGP=L{cp#^Xz2{(- z(`BBBrxZM_!fLA|1AFxgT07e?~`+}X?N<$3qTZLqx&1l-SVV-pG;DKs9OLa)~%{ypyu(N zWjxK%W;JDa{ZM(ORWA!Jpl5<7&cTuv2~U`Eoy)Z1MdSQW)3*u{6#o)tuuP5riy;+< z!9&u9%gPbvEg1dAoxy0%kto||g1=V%K$a})!0ptKkybLN zyp=RT5~E~u?sY5z83Da!AqC>xs(!36hW|^FByfn3oG10+KwHzj4EvM0xFNWjkT3r` zy8+84bcXXu3~n0EBE-tiWhY{xa@X}NF};j{+{&({bX7{ET_wTAftXiDM)I;tC>cn} z*hgEa+;g=fW|j3KceC3lRZB&;tDs$+h(%=+$Zj}?kO04|orOi-T~}LTW?45es&#rs^NZA&hAXMk78?0y%6dYEE6Ie5@Qi1h<$JmD_7z9Z zO{*Yjw%3ORdY&~r)31E1p! zOn|kZvt>dtO$lma6%~ip=Sv1!ZcYa5PWg_OlP(x@9vGv`D!LYZvS_F)8VIQ_pd*QR yTollMu%c%!8GL*q>$!B0I`!Hxlmr2hDuiBA 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 z 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

      i@qByauNJ$ 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%0Dl1hA#M+J1 zm)s~HTO7GW>Yzyx4XWU#E=dQIiuVOkF;PTKb;l5PB=|j%%`6(2>LU{$@B=BzN-V%A zvVL%15<<_GIa7qRZ=L<3P$h}0F>}$$j?&3VgCS74`?#@?t~Lzj7)N#JqEyZ=UoLWa z{28VOr@$SxwW|)o&5Qp1)=3s@D2~OYYl(!7_xHuA2L1y^w~um|ZD786T@7g1@RP2} zN4paTJpi=YpXXSaP>t9|9D~q&Zr%F6#@)HuAFi1Hp+?n5Dh6I`sHe6VoOVe(T{ex9 zFmg%$(Ic&%O)h$tEa)h=Yse0{-iSqbN`bo|R@Z=85_EOl!mV#`w_jiX3C<9~MV5C0 z0y+!vEZ!6K?o#S{QuWs;d8H|3IH=Mc-Yf$7ce&U@jofca<8U%$jKXB3A>L zwMA6X59+>Slgn7%z@d$O=e?fRdCv__5&~ zK+X^3%5Ia}JQN4VSw;#csxnD-ag;0L%6#|_J*P>y@E zL$9MKB_TBssl#dnJZiwlvWGE*AD@~D@Yr+KV`H0WAf)7rrz`ob{XLb|L*`gR*=s7y z^zOqd)JwZ(Yq)~;>tJa403*N$L)fNwwtawVBa2-RH(5Az1}# zEz*)%&58)hQ(s74`mam+8x_G1eOST%g=`ANCfk8a91`6=-lFzm9NFyAo6%}da$a0% zw>I*fA>YN`I9fEms=n`Y)rh^zubM68Cilq~t*Wn7HnbI94E(ydhtLDnMH&J(S?*|R zj6$0lhbX5j=!;KWok_}OxFeDymZag#!M`mfXj z;v1D%D!rKz9YC0qPypWKV zgRRcD)I5^Y&;Hl(VH3QYZ?H~=YYcQnsh(=hI|THIPPiIuw#E%7n`8c`kvR8F)=ZlXD-vt^{fkT|Viv zbVL!ebN##ecR-J)JqCMFI?_qBt1QyxVq2`?T4Af+(M>cO$jJKR9^`~rL+ z3;MfQ5-x>bP3b7AYp?G^QuDRxAY@@?`LxzF^ckiUS4YY{vA}n2{JJT8{?^$!z>L6x z9I4#L3}J16dfnZ9vo^Sp3hjQc@YvZBX_Z3O<>lwM)r?Zr-mgo_la|QQB(xmm=0y?@ zvS}Z?(a4oR#ujTPu|XVK7SKf^vNh@ZtT=+W`g9oHq980`5$xOmESX@2$s9u!WK zP~lX#&)q@U!KX|TAK~nNv(Wyn{dp9A3#6jwr_{B%(|_HC@M9l5F0_~e(vo=o-)A$* zUkE2|fqad=viL{o9-=>I0|1sl$M6tXxfX7kf(4RBm0a>(mXRg8>%PCbJ3V&bPJ^1$ z7oepLydvQ+9w|j=nJPNqdNs4ec_`)1kD|U}f*}V8-Eh7HbFLUV^fj}yWof25GyAL^ zI_~umy!Z(hBjk>ZFT<`T#{JrI+Hm<9=Qz`+5ou4GY3hk2SYkrSS0+JIs=z=hU*6hS z&Ew9lgnx?&2rtmSM{1GgqG#~LG#G=gObRYA;tL3fRJ4J*hNRP z+s!~YH z*+H%*QrFj=C~T<9;+RJ*7a3nVzCH4X7PQfJr$2}j;KzO4=}}ZUmunawR97-sP0|xe z&bt$75V{@#g|$RVD=RXYowt`si8wWs=WtXu;5``9QONqvGg1`M&Oh+tk`iH*5`Gza zhNocFwoAP-f}N+*{>o9Muz){8(`+02+O$=p*+20HX{V%gJ@b;&E^%Btu09%Q_BS{6o(M31M>S^oW#^aofS>VSm+b|C(o~@ zu+ZW%R$Z@uyF^AI9oeB1x|feibVb3{EOI>#s0!ObhP(u}2flCxwQ^f?wy%ti#aF#o z*%-}c(3m!TrkwggSG}wNf-{up&d|p?qE-&`5iByw5?wtmStzL3-g&oJ=h)9-(_2$9 z)I28y!XK49n~`S5%-4k_38C4a&%-FhbbdugCUm^-e&EN4b8kA7oEYDe@f)$eIcbnF zQfwL#ba_%FNqbz_=h{N^gBw22Owh{$DdWD|r70d2Z!vHS-##Pfa$BU}0YtkF?lKoW zutGr+RC{R4<)7W7HZ`2P*MBNfVZIG|<3Z|kKaTJl!uh%305o&*;vZNFrubgyb^V{t zq5b+l?L*b{f8GtP(*JoYG~kejqS7t%3+W5j_)z4Qmyvndy*lwM`AKA~?j@QlEPj9d z3s12n>b1xX`8Okz^~W{vV}~6{oTi$*@{f}cIEDoO9Sy;=+-R8;ywmF`v5Ngde7Yf{ zn(A*A7Vog@8KFdmV}1RfXWj@)GLXI)`yndHcctXzhwX>gVFwxTi*mjKN(Jr=y)aWu zq4$U(V7W!91nN_O9`G|}!<-e!x46(n`*5%n&=f45+XG6PWVr`P{Vh0-T_k2KK` z`PfvDIr-X{bp`N7P|G0wbzN+_UAEND=^*4ejPkD>)tF4DdT?7EK?*j}B@CGyW|EXj z08n+T>jWBN0Ro}`GW=&nOEC!7r+EPf8s@kSKEkA0a zD~}*D)YD|AYd-{d$45zh5)NV`ob?t$P*ts$|4zNzbZ4+BIy#WXLm$-CU~>{mSUG$& zKxPFKh^f#AXDqlT?`)Tar=oSGY@!1Z^)Ex@2Vj!e-gQZeM{V%|9xN)Pa`Nx@gg*zn;Yc@*=E_oiMR zmrNAY0%=j;g6*}r4bFhVmI0kX|J1?22Gn<5OhzJyV8gS?0|+wM!7BO^6A3~OCr;ks zBPbDxb_}nHr9`~C6MBpkow=B(Mv~Gc3QM#%CN^)K%{SnK@NxFyjN1wqnLd_}W5#~a zn#VLCeeN}J?Kj!(9OpPUc!ZD*kjA0tb_o=@*UK8y<6~@}{v3tsGLZB5mH2dYrY1(7 zvaa@XPEvnoYqZvVtUs}3D=U6JhC2}Xxd_l6!YX9S{X+fp%DqCj^vZ)mIZ5x+&+6ca zI$8`nCMjq=^V}`x;E)!vS0K7*U~cEWjTX(-w^LHgv`(N zrXrOWRaW)5dyEOq4H#g#pC07Pvyo?;QoazE=?e9l90ih@ z9;W9H?FvSkU|@RlC1$Fz!xG37qOF?5{ju(d2mR%veMS|>JCGbGV6Jj%xO8SyHa6R73{(cELm5QcQuX?)*}po8c$@o@ zlvnDr*|Wdjtj*k4UwH(h?&u7D@8&`PNEz1&JK($0!v`1_o3p^l` z{9l#9KiBPloWGzx_|Km`n~G=o=VKC;cH>tz(nDT_!~Kr=@N%CxwNcXSe2D(e&Ya*z znEzM%7l@_Hz0T~m+WiN9*LZG577X+6R1_W( zWWXQJoXkZ_lLhgQ!0bQ0qz#W#NaVES^g(jbL99|6es_5rU!Y=hl((u8{wNWvd+kYO zX8PGsCpmXOk2Am;ZjPIydp1=2bxb+h_Qqsp7#0O^UIQ1wHDwsZymWbwtD6$8XA&Md z+5Yq}h@H$QIp%~qm4VMnpg6P)b(cfBH0mP$JaSzQR;>$V7d*o=x%#PJz0vOl^a>Xq zxJ#4R!<(VjI{?zdEf`J1V)|iwS?c^sj`f5@*$=JoIsJFDDO1DVTGg8E=ePb8J8J7J z%F=IfGoh>cuN`^zqTt9c+Pej_x(|N*6nwmL_mtH9R#c$H-&2R9 z;UhtV<)VL-Mt@1Zn`=>V=S0}Jd$QKn8 zBpzbAU23%pE#0mYY+UmS<>>n)3w1DtorL4k(gw?f*zA#Vyg6>ejdGud-Rx(XLK}o` z9GB@HN{rH6V9QI^j3Q|)x%Wi@_^?5*aReg#R*$+OWf0$0;Sxvg&^8%QK}Z zd6y~9DhC>lIm5(3+RdS?*RW3=6CT_3uRcf)^%(6XOebOos@Uq2oH>c&NirX;c3pk=3q<@Z=dH&0k0IzA$ zPsf;9a>YGMz;(xSGiWkSXkFplGH{~!UClZ|xU=j02++)&wKJ(~YGMXQ$M zP_Un|WWo6xrEc!KWnj=IXm%M`n2jt?gHqNMi`YXbyH5(kZw0)P)W61Tq+>DCI~$Rd zhr6Qm)MaWa!H8Pp9BN z%smfUNSrls=~ojIU>s4P-VDj=GZJfk(fsn1qI7!`v*+*r?Z5c>pS||?3bNEL9&HT|4vPVe7#o^YbYS^r_TOTs65vUk52EcQL$kHej)?3vU`Jna64pg8myhDE>Pel z@GD8<=qK!n{E#~>MPQLgNWgo31rQfAlu}!n!bq;_4oOV7pVg29r5n<202LJ1=|%Ti zFX9^UQV9|ah2}pWo_bce-=Vx;wbG_rbYF&(rAgTxyas7EkD=*xr0m>;#b0HU&F3Hp zE^2!3=s_o+n#c3;W(>K6CB<0Bi+=*uKP$+rGr4M>4z=*jJ{_9no;^A|z&(3>c!ygQ z``ewt`>!(kKwanNnID}$c-V4YSD!oI(up~+eqWsO@$}TjTJ%C;a4JDq{DcEH8P5t= zA~pD*d@j26=hyaJlZp4ewa0)sv5=2KIaW-YVhy{ix~E}2q_YOi?nRpHKUQPEmSEMn zkJ*w2T~j})diPcLrQVhefid#zAZKaPUd`Ie0)-3v)gSaU_piVG8p>#be_SY(D=a?L zSPY}==P)A^qF}YJRenDzO8vru8(1%RT@WiWD5rJw81gp3K$629awxSk&32UiCl}%Z zX8lVw=L6SeOLjp=ybxg&i02?151+K3I78NN!v}562snr@OCUkVXLSc$og4&oL8;DV zxS6pdQVFW2%Psg@07NK|!Sq!~o^s64kx7Ce6ex`e*~gOb2lxo*yynuK7(Z zBu9HK)9%B%WucVWa&TWZPko!V2RpcU6$(_D!|6P;k~%zFA0bq@9Mrd6LLzkXlBDM2 z;3ur1lUXh;T9Bk@wu~c>(^&QNl>V-{JPh)jqsWYrW}o-0b!qHI<-=${zbW*#N_@#D zk=1q2yCLzd9Z|IC5B66!I>#n9Pnl~TvMqpe=MO6XzBck+FyomJGJXc>^3mnfZk#;R z>vjhVF%4a_^dPo;^r}&Xfcj?PY@LoA1q7*q2G8WWn{Nv4h*(98Ys>gxPvgH35Wu&B z>GyXMy*p|0aYFFnRPBvF!Js-F?6lx86Er2^l{Cg*pUfiT12rFjRSbA{3PS0TaP4Ji zLw3m(BvThSbJKEP=FdpSIG-aECb+3`@y)FU<<2*LTzAtV(gbi&v&==9i1X-*4*BgG z?4|&Lg!SnaU3)s1(xpiKS~&)0Tc&sqWS8teC-eJsNYuYhYR7=+r@pJc;@<H6=~88RxTmLz??0zU8Znxc7^p@xx2gFT9;(ra;2QxsQufHcN80H{<$1ac13fq|NX{sb20j?BSCy z(A5yQL4m|~N1o|-_fCG=D+#nap_90KO{+SXu20{OsyT9)od`mRB^$;2yLj~^&I#;H zkF++cx@=Y_*50{b9aw$#qMR_2w0_pZ)LhLE2_}v*!3gZes7Ss~Nv*^OI7Yy2vbD)eJoe!_^{LV=#znUmK9+$&KS44saP^vH(gig49O-P4un8En*4mVL{C5}13>43&Q ziM+zAHg;hs{5|`P{LfdeO zX)v1qN>vtpq%IDrBu-gBDnZl1+9IRUXaQnLdgfd{@7Z3+9Sd#1z8!5oXu9Jdy85ZD z&qRbx?eK;8hB6Tw(e8bIkB@)d(8=}S|GCr+fx~JzmMRv`;}|WRL+`!~R$7a-sM&47 zC{OS_aXz6Wz#Z5vtq%HqCzceMYSdPi9iAHlKur8Y90 zi{AdNC=qXo?KvH|Zzk6u4C^12&D#60#F?tv56R06CNA!u?-Mue4>h3KqBy1>G(F=d zAZYitOwMRA*igELO7hgkBmL!g=c7x8fDf~Vuc2fW`Cqp>ow8R~2pLc%{#{hm6RA-K z=)`}Q8c#qtz&{`VzP|bUZ(&Y4D^KLiOc$GIF-K~6a@G#Q3Rw{bc_WWf#xG7dU)60n z$(v}F7xQAB^;%H0KTgN|kho|1W37DXhj9rjFidmqpLuup#9xu?n?K8V-02S{I>0a| z8$D%y^vi4*jOx!$7M0aAwcY1&;iFVn1k3$D1_iGjkEt35WgcU@on~N3fAj@l`Rwz; zVg)5GpQ|~KA%I42@lie=OvlJzu#AE`79>aZZ&jwVJ}wE(-fWo5lDEGcl9>+EL-(kH zU=UcLu##iNl8+%1K=G-#V}^3XlM2Q6#z^s*PQdS97$A7F&t-M_M|%aj7aP?e#o2zQQHJfHMy!UVP?0xiOi&;WaA^)2?oJ{FlvA zkNM!j@N7eD_Sr3)p>as|K}bP7B%^L-a8S~EAar!(oy8BAMgJ$QYX>3l1L`%RY`I$l z#~lVBG*RU*JJ)Cp6}%bA-`*cjpJIAt*Q7?xU;MK;=9M1UG5f)_*-~sOZnyC`IF_}L zW_gr*>}Dp|fFx4_($1+~QN{DfiHbLspqs{n`K%u1y2lTh{)-rOV@b-QH(u!R#rj4# znl7SirfU|LPG`&2)?D}&@Z|hu#qj(79}hFFOHJUVSR z!QL$M(=)7J=4U{dn#@m+uqv6KeqjMJSHwOnf3sZcnHW;mU~R+C8H|fYPrfMn+cM|C z!r@>Q4jm7Y?YhHZ*7B}@D|7y*zL!Zr`{)M>xbTxojBGF-%bn)W)GNrR0e&VC7n{at z(~`gCkjSCc;1&Dm>t}b*beZc#p&wvTI{b<+bLrBlg77lG6u=RQipV9g7Fj`@ywvw8 zhEwU4>50G$30Nk?tXk3MBB-)}EuNh7mCIj>ejcxMW*m>HswNJU8rMV3qygDj0Djh&e>*((ZJDq)0dDJm6X zU&_9_FQ4!C_dLJf_qoq~KYw+Ob2^1-@8E+3xA(&L$iH9NQ!2Bj42*3;=o^1mVzbjNRt0*sjcD1;Mr%{&gJrGF zrUbjyqR?sIO;yg9uVvyoXU}o!>!>b#8RCkDyLRwpo>;y!r8bul-yS&CaWib&tX|wm z`rGCqzSZyZx38D*Xd7FGtj3vO`^F2kcGJyFEJ=M zRNvGZalNyCeov9`=2k zIByP2<8~vxmtX4jVnFnWf<>%=CycJqS(Tw+f;orroPQZ2=dCpQB)FyE>~_tHNR>mRpELN`jX7X@WcV(@_%JS;i9Du`h z!v2YY zeG(`g{j6#s}^i$r=JAn<) z*m+ZdRyJpLbiG>eLx=dA`bLhy7B}OEe39Q2)cAxv$s>C$L`9sb_aBfvDF;lfZL#Hd zCCYsx#(zbuyMS78b7bfDX;2a>A9$T2kyQ>r0pF{{Vm1e2#Qexq= zAXpE?Qq^*q+8jUsDmy*!o?kNlIWI!}F@TQ=pHl!_1a)xaX@VB=XGzBZh^tXB1jN#f106vTmBR%((IG}0dt$A z_EtLGTztej97{F8`3au=+!B)FN*G9iUP1b7;C@+2Nc zjm@thk^+$iVviXrr3&FZ4Z>Mc95fyRcPG#ofJZo?lPR=-_nu@J0T@a5A7JE$S z_U4aDVB#22a90+YL|6X+{+H9;533y>O#KQ-{|iE-8KGKw$_T2g*tDHa!1)tI#_KM{ zrM;zmlwKRQYpOZFV0@2r_C{-&8X-N5YV*ozLEqOFtwLO|j(?&18Q+?~j1^tK^TXnM z{ib;ym6BcI3+9vw*OA_P6fner3@D4G=LmWcom60V$r9^`Vl_c~GRYMY5JKC&5$FvZ zvx544;}}<8lNy)nu<4Lu&rNx^zGbGN{5EFYGD_F|nB$`kwTe4e9^R;vtEW zq(&p&qz$yd9|O#$w$WOyuh=LVf5e^S26V=jCg_`I7rfuFnTaM= zN*d)cXd19RW^NKhfVi~^!eKE5S47{QGF~cbVZZj&B#G%Zc&j*#sZPocsZvEI58kh| zYN?bQ3~{k^EK^4QxSxcO9IJoj*Opxyb}fMvi`jI_Cmj0UZCp(Tx}8rJT%Z4a_v+k` z2&~{+@S{vjkEcZLWT7?Fc};3V924AYXS>v&Wv3U$49OkepA0_t_jn6YNG^MOuK*W&K|8V`-UY(!-Gg*oV{as`^&x{#XMLoRDdAj5U$#kMq#(N2@Jm=w@<*r z-xze&`5v~Qg&mxSNj;VFDhejXk|rJR=yu;cyLDI+lXb$XZF_Q?O)-S@{^lKNk6)J` zMF@`RnJ7QeJ%63XRb?F`j1S1tThplOwPG^hmG2{1F_d@Cd*--Ut&yzrkZ>Ce1ADa;Y8u963+N3o$8Y z?A%`ZD^R^O?9SV$c_GMPu{!w~=o0K~qVsbpUaEm6u@|pBZ3VgsnV>zRA>S2v&F4MD zw}KVv7q`+!C#s8MQ}8x?7=$okpzgV9yda~g6`t)~?>GW=eX4${PIqru;Mc3n;KID- zcarrw`O0^^A^+`!B52BAvtt}iHCFHh9KBG*6CimZo@e>Ug;Jhni3?dg)9)52$a?sX z#11{dWP@*_f_4eGs7!<#q9840Qyy`4UysVbxG2n>6s6{Ffx>-lk>5XGMu}6cSXC>O z3P8`+S~gc^lK;kQ-DYL$R?(2w5J_f4<=IZqC{l4fCSDlX7%Ufxr1)Ax=i#oU-H36nS* zilBdyYK7nfq!vpxeI|rZ9=WuNBE~`vAiW}$gY5`MkAu|JLIfR+3q%68HPzk@`_gCX zIgt^a4c-q;g<=JoU$v?AaZolT{e3-Z7jMLgzH|kF15Ci~UP{Kxf?V>&-n8uWBT`!x zX+Zt{M25a;T$}^Jqa{f*_ivj2xu>US3`#|L7@3@^fqbSg%Pt`SHYmXbuoS26#pPCX zbK{sCuP@T{j-2N;{EYTD{EAHHU#2)7;b>re$j}C$5=WcaT`D{UNTSwM5 zAG}c6pJI!7UVlAHCVkGXer4~ijyq}|oo0&EX`c_6~9yI;VvI{G5FAlu^c~z&ya2!}yZ2;2}MM)=RR zW|)c~o2nK~IC3~1X__FLv}{G=@mzL|ADf8`ZynZzQZ!n`Igus6B}n@^%I?J9AH8%- z$NyY$#9s)32v=G9LOspG+Y+wznA};rm_wQOr|y>KlrDV1?%X=FJ>OkS++2RO$n5rs z*bI(1Z~3PU5~|slApS!C&d5UxWT4Z4>*d`J(UQw0C! zyGnGo_Lq-Ti~GfgEXtUi)MG`*Cvzjr3k?X6C9=G3}X3ijNW~!+y%!;Hsca1Ae+m}&H6iGS(k@WnW4tmKGU?dRMjpGw~tm5tfZ_ze5v0AJjGRzSspLL zVR7W%KLR-S$nR?>xr5>;fM-|CuPqXb&BWMXrMF6l^a?k|Bs2dJJZbqdfg5hyyLgvP zj4G_7Oj;mh@^Wio1+kR*E<6w~CE`iK1Usx8n4v$65EQ5fawsrFff3TAmVz-fJbozw zEKkDBLbPl_%UMY&z4Gc1^BJ(`kYeY@jnyU7_ch+vlq}QCNQTkU_QvucK$xY3jF8eB zbGU)Qy(oB0qG;lDwk(|EzPN3~UwXv32hs0^A|AJ|xZW+AYLmKq!)evAEZ+Vn`pYR} z;=ZhU`DDX^)CcrOZ{7P8dp0e)>%InVh+Z7}u5b2bt|x3oPtBv_xv%o%8fign3>l_q zqAU8gVsRrT^ciG*qY}3p{O3D=>-1u;98K5y72&ng1rVI_ItpG}pkljwLaOJd#QmSu z)!nR`Tugb^A}St3X0OWkFFrNephUx-%&%E13IUFu;K_&8Pwi}^y?8ltFC#rR(ie4T0 zS&e4i5Rbm})Nsnm;rEiLFMhs-!(`Tk?@BeoVyfquIqm;0D z2bMxsPQk!@h{$25+^O)HnCki5RN=5sPS`-GX8G?4$B7Ru@WIt24b4{xxoX4W>Mdp* zkN8A1E`7OyLO8GIcg-h<%9t*EwL!fn^hg0x5^d#ylJf+h1U)LZDj6up7xLWnv3Wxb;uj{UTnx*3PzkHYVMch{oiApC@D!_DR z8CXF<*aA-|sJQTY^6YXG^kk>sl(--vjv@vKLF`SjiB65qT{{Yoq7`FL;mom(eObvU zP}i(%EXI@U`oiAYCj8O{N4|fMg-4Z-3|$Q6F>uR!P+0&UkiKxLUHa%`TAt|8p+#Tb zFgLfmo0RS61LK7*jtTPlw}O>v>;GDTaID@YaX-juc?Ye=5}9eO##xzZwZ=@DY0btT zGSerBVGfxm#v0j;NIhYcjyJazDm&KSzao1LwWKyDi^XRO{w0G$0e=sTgx>i*Eb(1$ zRxN%~Vqx4YAUm4r{so@|AC5I|Ek4o?Jg+RyHf+5fs_!88j~lXJ>+)N3G9*jds~UOl|Bk*&uq z(X!MS%&XsUYh7B1U~eP>>1yLwa3j&bMZGs`v=B12O}@f7cK|_$fiwJBIPNr;LWETL z^yQ3!l^&jPhWZ1|Cy0HDb9O;2H`g2@PwL0R@EY8H|vQJQB7JN-1I`&#vU8!aDA%TjVeqCJck9OH{!zJt#0b$0B0$B5!rXG zJX>AmgRNTAl^`i1qHj20YYgN}Ru3o92hYPYhJTL9Y`PK8Kl<~GXZFai5}w)2pP7)^ zjGuLo*{q*z9?G->ola-}`Z80(UsKW-Z0?~xB^u#c?~PAvp37p9BaJXr|4bv^wT}yJ zjtZFqqJ05FZElm%BRAt`Lw6wc{d%Le^(t<>wvH-8fwv%p(xEq!Jjrr>mFgvOyAq-q@L5kj;64vnpfYT|@dt0)a-CtITl%xlbUO&l`z8|b{>65B4$6mg}qBKMC z6W7YjWnh}->1u`Dx@E(b(h)k^<^(L8A|1T_L}q7a_nW!7ZsW!o~1{ys#YA#nzmTp!*5(cq|-;;sKlo6jOll1p=JrrvRygpoDARsJy(-*>TlHiOzuX z7PQ>UM)bh)Dk8k7rvpDQkC7BeYT}J@R|3DPG=JK@DLG=@j6x;L2@m*M)nEq#UWc4P zL(7tw9f~eCIY(Qxa?IgW+4dbbmR4a$V!`p~C1&{PI-*A8WAg|99T& z-@=<+)y;pgVYRXIU>+V8UH@dQkfT7oCfWw4RjPI=-5T9IX4nhue)yPDaZ$R@6cbHX z_t%XN1-G=k?rawR!pf^=-HN-{z(%3_dnL5=?#P_6CCj_^ntV%P zyGggrNAgYjGRPoGdhm9yRC+X#i9w8f4XUW+RVE=+sQHSnWqeY<+djGvTt5tz_Q**a zKys|@Jt=8{pe7JpNEVBP0qbe)U2l;6k!=Y!zOuZ7A;lU2U&e`1UOubm$=Vz_YWKy# z@EOS`rs4YKN}_4(Min0)>6IEz9JIZXeC8Av>;W|fh<9$ppWC~WvX8;Zmo0GD=BJF2 zKmfXJxo2Ptk6!k&!LkWsWf}XxObjxWQbd!0?3@H#^?+#q=MKZRAJGF^^mOXOvb6m` z%k%*Bw1LB(fJ*c(>lzaCG^sE!c|RvbdE+v^_;a@niDzhSDhvQ2`gzH-4<)Qd|No3P(u)pD=RuJ>;Y^V!P)7CCp5aoY!_IL9I0fh(! zeXn!ys?;r}{4}p2ndn}sL zUHLsb0tfLxiGSinRPH0|gQq%r2n4>vj)n4}Olc@70sh&j$^|Qqii4j3Y?8D}I(kOVO zdhgnsp^fjCM7dQu=4ysx0G-K;;FT6fUSvU7d}s(~QnCq|pfFZJ)+wel+%T{ToHN?{ zrg)%^DE7qp%4dTgT*pl`;7~jn7kluz4bJ4}N!J9w;Jv}ur)5?|oi~(M=eG;~aw)G( zvK63uG`v2>ZO@m!sn@v3tiQ@Ln0+CyN!x9YxFQTFB{})x$m+hla27O&LQFs`n1XXG z7L~~k5WLst&YSMGP=Q&hfZU$-6E_l?=yhef(1w5nQr;tXd7Y8~mGDYKs1>eyi?ffZ4*)pV z#$oG%hcjIJ5xPZ+!FRGE%R$ViCB&TlVHAgzp1uAZQWSeX!uAJuT)yqZujmnwD%8{? zWCy8IP#(h2%?Z-{zERCCkMQe74HDv`$rS{j6!*8CS0jbXvf|ZS@fRPHXfCf4adp?s zjZ9o6%S+#MdUc4$XO`|LI)_D^clor{RCU`&7FyC;S5w(Ewl-C@mB$93)1IfkiLbLb zxe_%~z3}K8aJ~)uU~3EHa|NXRzrw|rMxY-avm1jKs!Qi!U7~d^tq9Owpse>=mA>CZ z&E6wfL!bLw;9MMeRbBYwLtW)mv?b6n1;*8OpQ_A6TZyX4?e^{pAi)l-L`NtOokm21 zl|`7K<%I!x8mWe4N!~#l^{fHQB$|f_@7IYvH7?k@NVyF)^ry^W{V2m*gZpb%!+TTm z=#00Bms5-U=Hl&OOI&TvFBt7F35lcQcuY`sP01bd7|vupd)A3#pm(J+tXb|f>Aws> z;N$`__saj5%suf_bOI$YolNboG#`*JKEcca6Zc-C*W>p(-N;ux8^fojbhLcE4*0d* zUCawT-=dD#4?p1dsCFm}t&?^tGS#{HMAmY?sf{!-%9jTgHEiMGyC~Qk?lsa|5_oTZ zeQ&MO>!P267A(3OLxrYmPhfeEd29Mwfa)=*L25Gzk$9%%@n*Y6VA0{h#=6!z2E}NR z>=T^4_mS4cYxnoYscATUlDaCUR>&s9Cpwr7=R3@m>xITf#tFoM);JI_>X9C(2(t8^ zlmj*H*1C>-z|P`*Ja7|D`;yj@wpXV{bDFyKi|*7?=G9~PwSu#wIs39H>brE(Gxk=>>j-aDw5Z}TzMpw^&3X}@Tg*Y1%9=9_GFFB?lo`%6J? z%(4LL3wrPO5~Wv#uV5wczb&C___1pv+}0&~yct zN>DVV$tg>IQsqV}yL$9dnBPa36n*4Ney4V%-rnUCW?5ZsGPyw>*F#Z8%xR(J_@Ny# znSDY89NLPg-;3I2O?byLCULy%l#;(GN8Kl^_4c@fCp< z14gq+`q7J-4oG0p_Pqdb;@Hkw=aJqg9KNJ~y*+2bLLSeK_DZ}ldHr|#@FAq!Fm?$> zQxEtCU`pQ+a)^6YsVOt{*sA>Mc@U5KqQVBJ2>~IH-KO2+@MIjw zc&$wGJ`u>q3CArMs4OVaM2vKpShMWdsgVkU*LR-1n5pLXFo?Qd^~C-ae{q9nRrK}H zYn>34LQoO_-a-KM^YJivKcvjhydBU|nlbj48Q466@-TS(q|UE?_EC&L)qog)g2GAD(WcAVXc=w4Z{_7I86{8rqswFC+W8Khn#lRDZb(r{hoYz=;#TG z*`lz%c;&;b3SU0rq~gBW{>OM*_x;+pE%UmFrYYXCiNH2Cz;^*| zNidNyjabmA5vT~1aM46A34c|Vt}F`KUH^=@ghi6@_md{)KTh%h=q<>X*9rMCAr=u1k(U$zCV;tJ;tg~Ae?nm@~;jYMG=)bkHMM9}vINginIlW};!RGTkDB|G8F zBzo6dVThIX1tbw-x5x*Ktly{o=`!g3dFIVlOm#>=ixj&BXYxd@8ImAt%baQ}j1YCABuy^e{i0BWcy{u8QEH(% z{MsP)mP=JeL*?n-$8JqRIrl0AJBX(e99O5m?eyn&9@{A1c$!C_|2h6p^40m3zWXjR ze5&_u(x$IIZi@@~nWY!7(8iax?(@{U;YD2PJ76=SmTNvYO~Lt>%w0>PW199kf)hT<(mV%?aYA_&+>^8ZeqD_J*A607s+x0 zd?u!7H?E?@Y$B(0n*1>XL3xPFdnH7W*8%y`?iK%ysulBQ?+?Q$z zsFjP+EZed8srjCr%{+Y1{F5-t70DL3AFC}9XJ>jrz_0Z=gmCQah-DLK6{fn#Xm1zR(M;UJ~Bb2qo35yi5XlFG++XpGnnv(=(3XmgDusG*d_; z&;kKmb|uqV$K5NagbwT{H4bN55Cg?RcB(;POK9a9YRM|4=3VZ?-d_U@Y|Y zYTE1kzMCh-s%(n8#;Rti#W#aEE-lmwu_Ms}&iqdlz9lf!thjE`9=bSn1PVMAX zAfK0y1w4(;9=N(eF#>%7j}w)H5D$t@f^TRj*i7o#^eMEFn%#W$W!l&4zwK(SeSK_u zNQJumHRpE|G?#i(^;ClQEZcmY5rL%~s*?Nx-h9qsyI`w8?ZE>PF=TuD_l6IrJ>S0y z`?BuK&~p7`h;ongCB;F91R!cngh+CRgb)E4G zL?{(8F(L2EH- zp8gUd(+3cQ=uF1$;C?1!d2@Djml>8bt3C5-a>V0%A8mTzd(ym*?%fj*kOQX`GsWSg(V}nG1ua`Fu++5-3!l=4eNA&^D zKJ095#tEIfwTqF_?Py#yeIWD%L@PF!U1X>b!>E%raz+&#(KSfIB25*DgFt+RZXNE){JJ7lz}lO{v=HIC(b(rwu7 zsZqB&=i=FLMds3K)=RY43)RI9iGD**F==XI*JJ$k(4xCT;9PPBs%BG?G!pP3*cqU& zleGCG(2b#|H~XGTu|*XuvY@JNm`DNykI0X(v02Ik_7gGDyQJ}V=MwRt$NA+kIwh?F z7>p}mJ&*AX+=Wq&tlsQw3>w6XRmPlGpbIA07=whpUKGTGCSEe#1G-J^KJ2HfT_R;x zIC~EU(0Fg2H*Ra^E=gBA7|zJ zXVXghC#p;O$9+Sr9eDaIYXS?!E%Q!GH9>0rInoW7J>lp%_{<{m+gCjS#4F#bjymrVtf#wf2YMa z_6&WN_r>JVP6|}VW#-J$rVhS_1{|PR(M%BUE5xDryS?%g4vn=z4d`bc%dKfC_flj>3nA3cA@i`?cgJ1 z{7jpV@3~GBoEnkwV#^n(!Mz)#(MA?t0}nZ8j9LwhDre%|WvTxTPWYD*^4}8x@T&hS zPT^l))m37VkDm9kDo;EEwcGWmhqx-!4|UEC8UZ2E%YB@7>86~*=*N;~nD;h`7({fy zv!p1)>5GkcnZ)_(3OaMaaot8;I6>QlA-_>DNOT}x8)!CUvzr$vhXBvxc8MR4gFva zw77&vI{5p5GT*k9IEXzY4RRf&Xn=?CPahdCRLYm4|50_5bW+GI3UMW5AWe^)KPH1|wFl z<*;?4BGB~+zp4-5fsRHIA-_l09?()Pc-_gPH;d{CpqES27J`SrzJ$kGcT6v%+K$3S^r)REv z_V&7NR7!3vdoA^XSigbO{+l72RYL>kOPZml8?Xxl*1sY=#U0x=>6vea02KET?*fGs z3|mI$C(Q=?%qZ&w%7`xN0v|Pvk-a_~x=0S#Q2Y(LAca7Jjh%$Z(cM=+CE#!fYfmDW zwq>4EaWWgqD|+G1c=${@$36@nE;NfrCJO zLZMpt3(vGYJwIJ#3gqe6%K$-XRW1%b)eUV5`z53V^thPs9)$BNo0vkLUZ!ri@p3wE zgucB=o0ocHVhQ1fbHSKYO3FAKXm4tkgpmbqh$LXrW%_#EB=RbiMi3E@Xt*kZ)<9w! zarO;}g&_p-BhnxdLn&4bC5&O%39DpNqd>Kk`Gc0+oJI_H%wg+Hn8wL0>eEd~Z5o7- zd8f!v6dlROvP#5iKbhe4c-;QHEOtq0^T+1Rssl&e1w&^!3;m;Oz7ZD%f1NVnU+mI3ugiiqXg+qgu~l}QSTrEmIIcx_ev`iziZ`Q4=iI6P zb^2u5d}hRkl1x7Dx>nu(M+0>_Gmm|QKmb{GMHl|yU@`wH=yJeE+YMy+G@bd;r60eb@xX+ao8rP%wkOxrhXggjK?!(UlQ$Myq3eeK9wq32M*7}hh#KE3$kRmc7I?ibF)HLHG(#+t#?6(Hc7T|hfQqw-v4 zWS6xTsSuN=M3ssKjS7nz-L%ni@gHrsnH-7QgKD0M_Ug`ZB9-C(C{@%c6ozMzKOZAQ z@2=28nRHjfKbJWVZhfjtq;fOJ6*+d|`pQWdan*vx-*_z-%RG}2f|u%-uuqtGXmR0! zzicml{ThSQbH@wo*X$LkBdDLBkDwy=?F}@%VZDABQs{IV&)pf0DP_YF9qdg1C! zT3j0YbsInMX#kaWxknKBx^IBLU#Sb9=e*gGB|vC92SYBMmM5%r~v=)2PXrS zWD}4}+KVPOG1Ise{Svmf;zSei5N&=A2y3hym@=4ut($vJ_}Auj?jL!TKYTc(QZ0SS zHIzgs4Ypo?bMtIn&x`owBjy{MJJg}AovWpuvq296UG}q;#BaLq>GyzGP6WB2AG-{- z4W1REeAr?u%<5p#T0{1J*?7dYwv#Z6haQQ|tN?*lppadS$lR|0>t-?)O+oZ%WJ!oN zZJEWApYC>EOkN?=;j!9WNV{CxBOs_HtgH+1w-XUJ7d$1C{!*pr=`C;>dXZm+hM=N? z3do<=g^bv`nfN2y11}iaSTW&4rh;cLGzAY{XZ&vAmbG%c#C6yt1%RnbH;^?&&JxhI zi=X?92XEP7U$?*^gqO~jFNl{`E*va1J}IJR5(FWDNnv{x-@SYSh8g9VPdhbRuhsuX zCZopv{{k^70UkzFQ**59>5K%d{JGYh&~@iMyo@1o{yFrD?y}H3nxB?TvJdu0`(GGZ83+|4F>GwuzMrw- z6kdjV_k_->)Xmv-|AAe(7BaC_s?2xXb2{IYucy1gB2HvG&wgU(-De?SJ02Z+4x<@* zSvpumn)1+)ogaX{S}cBd#0I+D5$Nb&!#xw^oCp$^@Z@jQ{hf#f=_YqM0{W0`3L<}6 zLo(qQFvBuzu&Lfny8!*%T2jSOD-V zp|Np13=o&~5KO(o&rckqi@`najsGDssqU6c2zyt9Mgwp3TTRi#Lnmx5KIHoCzK1FJ z1nck>)+6L#u@J9)33D+K!?3Z0$mf(vx>%|Wg`M}EzCUcReDtTt-vx-oehH49*L&te zBo=1oD-MpFOSs%{+pS)4V~Z_#ZnSoFhjw*O>DAiIwJDMLksx}%(Y-17jzYpzwaeVs z5dMW)6&u5^f!MpUI9?nnZ6h9ht{+|>6M4$})1^&&(Ut&29yQC3fT^bGzG*=yf}r{0 zQ~pAU_`?$0vqz8x-`54e+%st|4D7JiH`gV;FUd;)_3V2fht=E#PSGY$u7^n7Ub@O< zpA!X_)a%0>gYTbA@vs~?mq{e~f>6kK%3BeN0W}Q=C@njVHp|S-*8m_4eth1`K<;Gc z6~%M?pWW}C{NP;L zttoYD^L<^(1G>_uXBAx}G4THi>i8ET^{)gEBM<`mPkhq9MpAxpq~>A#EeXrdO;z*9 zp}Yvi!iJ6$0>wTDq6(KROigUCs2^X{(iqwE7g1<aWpvkt^iRynkp8(`2&J5rmaRM4t%p&1;{buXmm;19Igf0#uumj?? zk}yo%z+-%XzAZB@-zy?n2p<=v-Xqs(2HaSE+>Aw4;nR#ehKrl3pY;>sOs&~;Taq7E zFMutIO$GQ)yaMF}@t|(P9e@G^#j^m9%KJ-G_6#)t_exK|hDS2t7wq%;s#eua#rRUDBKWKN5sFJ<)G8De52l`dt^r{KHQ#ven(KAuS3S${waR zK-#86ll7Whbw&fI6A;Kp*Xm~1Pq=(>zRmug0EFkCo7uWdKqe1dCDU&cPX5aMj9SZ0 zv)6EJj0hwt^P`jV)r;FwJv4W5W^p|L7#)mKrc;<8EXBsw=)&0r*v;g;!dMO8`KaEK zd*05HD38=cUAeLHI>)_fm1iL~rshjb_FXF{QOj9|YAN1%o3(HUX*UpFIMe@vL#Xno z!(f=5zOA9flgj;f^DDsg^xu!&zxSj6JdFF1OCOy#_)~6;ewtV&J7v)@Bsx=r|Zlqno7JJQ#=E9j+q1Hk;%H-Dt zlRg2MiJ=tAw17aq4D=|F)>t(uqs_%MiW{czZHv@LyrJgrriOX$7HXJSHpI^Oq^(Ci zZM4R`*`Igkwamx~ouH*lCo|i9&xVa}Ty#P5mrQ~)n$fT%-0y-m{2MfuN8eL=Yxz{v z`cBZ@neKgeW}3IM6GpxBkIzD^0$b&me!vcV3qxZ=R6tH7-7jI$9@N381LR!+yAd3) zmIumJs{gdj&HjT0eJYq65IQ(pB82oe7Zuq`xuu`L^0;a(~sL>RB$noYP;WYX1 z*g2%#$m6%0^rDu+?#ijEu_DT3)!c)c1!1H|Bw7CD5|z{LI!7ftV?;=X;Tyuu=m(}% z*#DzM0aT~!e^Q+Xy6&^?w~h+&kKP(Bnu^NC)F1s*0$G-1BYGV+dr`cUcvyEXe%FqU z`sQFE2qcC~5#87unP6P{1LyyuelUn5VU4$@2UZT~|woTqL?JWNy__Q{f z9Gg*)TP#Ins4zr!OO2HZr_~xXrUv|7x2Lj#?)FG6#N~JYwD1&Kw#tX##WmiH!@V1N zKeT-@xa??|9OxZPHjNS{oI1H4w*7b*7zBvC4oH(VS^k5bXSe%4XjlZ^Y5B>4f!Kt) zNV-i2%TUFTc1-{xO6o;p*}yJJL_qDpJ&lv0Md_D86u}oTX(;S*``ud-7-IGd5)OL+ zCjrPdv;Y?-o+JOhxh0zl74*I}0O<3Ck)w$PS0V@?1DNLxb%xp5_>2duX=Fk;C)<4> z^Wt|kF=d0jGmmSMGU9Rw%#9+vE@6L-?sAKKT#TRe9`oRVz zB4YicM5s&mGxtXYM>^?`IF?3gP7hsJ+)A0-Vt^6n<(ZY8{Hq)##Ye`h0XXvEWtr2; z^b)qzN0W%SKXs+5Dc0Ke_QK?m~4ZLXKqJzuNXX+`H z9t8(K`C7_=Z}Qa2aRbR;hlMtMBhFjh7~{Tebz_BdCHBS~Ag6BZaPlkMLTbtg;5YKU zJGlBNOGhV0Q#)AZn6Ec;VG8sgGuhc^hfIV&PzILdR1(6w*r;s|mb{#Csc7}mK(eg_ zpcV5GK@}9i*Lg%*QUO0&c=Ca}AzT1Ye_ZhS5+b+aVoWw2k%aJWp5@?5ZaJ~=bp;!k zVCx(EO4)f|N>$Euw&xMgyoY>}8*}NAZX`Z&&)zHVJ}}{)wPoc=xIu*r@ACW2yY@cN z(8Ubr^CJA>8XCqN!8ygehkkk(L2r|kl>PJbrzB2+n!5&AO?n{;6v!|DKWv#OjZBtk z_|45IoDG=`k3;)1%^CItJ{|;>3HF?5xL_1q_3In{BD!uG(F?REg6q=UCeDJ4lNo7c82q5=L)sKG0v0^+ZY-kf={S7qp>=ZgRZu&HT>j4M62X zOP;-|!(o4=A8-Uxijoi>m*ENuqaOuIQuRJmB%GdRq=qLjY;mu`{tT!Do@!q+clrC{ z?FRqci9IXXFk0QywVJt1h1@)}bs^R7mYbY4BO6@qFlMVB(!?R!JG3FbuNUe+ia#P#g73f23UU9qGj)0AN!w0Yh}vT@ zH7#J4-0@f3DO)p*@hQr-{XP2C&{JH}4!bqxBO$+I_!w3w3#@`%!r&)-Nb<<4A!?q( z3_BGpsVkuA#>ZX_tmquiHCg2%MLvwcC< za@)oxa2o7BJIKP>52?zic@5423DXJ4<)5S{M!Xs+&jx~j^8mJGfcoey#-2{$!w zec{4y+q@s~Nyth7EkQ0#^RpDN!{OHLlRD3?bPd=IyDeHaK=A zQkVth>Pr^W1XM5DIuP)clR$PoS)%uYS!gWl#XLxwmC04ek;)fwwwo-pbX%!C)qs=* zT2;047s+2AfKrF(I>eM1gb+@d4iB@mJaTsCL^g`ZSL<~$O?qX&V&^Wy{f2KrbP>8EJ z4uY!13)ATjeS60ObOpb1hA$=^hK7&i&?}NKoWczOLUuM^%}XfF?$77k66SSG9ZQJD)y?IEV6(6BbuHu(rHIT@q8_h!fft-;0VgeIpEL z;3b*-JqspI1^YPl@7&pZqT7tEb^FORZh>ko*#=fxS*_!$Ce z>iyLOHPo<^%{;`;DO?{ju9L=fWNh5QfqD6J;E}64N2OI5Q@?Ka1=l;B8Qn=Ok@P*P z)z9K~q207vCNiA%_h`oVL}{4lIbDXQl<9g1_P5dH$%9u7QZGnUcKSO^zcGa|{KUdi zY%m^b{%$K(Lmj>hQ>@)C9Dm40-AV&gmBYFEtP109-*RK!)B&S_>j+sAn$d;V&Rold zflIdT=KKY9sZ%Vd2{aN?^Cz0Do@f`A%d#RrwvM4Nh!*A^71uE;&-EmceI@cTZkQg` zAPkE<^W!q0okR%tUrqt^|Egq z;S&Dpp?8R&qw+O>(4%#Mi~ z!7L=0-@UeCRJe~Pxo}X{A=NzJTT2rb{enocwT{ciIG{{ksW=3rzEBn@UJ;u6W+r~| zWsaP?l2b#tfkDsF(4Wsv4^MO|uQ@Hmi;JVd9JCYS{_fa*#^&d`ZdY6It($T6`J4Ie zOgwE45V1+|Wtbzl6+nd~Jt2PHDW#cG!7rs|d(kd*kLL&oR%@ZxK5Wf94M%E5Ou#C%}j41@R6}M9e+DAWY8#Wm#@B}QlV8exzBe@aLng2qb zlv^V}6Nog+@hWlBSI(;Rvu8d)m*8#5$MtwLO{H`UqdQ(BKD0*NR8TztJ)$RNKsn&3 zkeH2l>v0c8SL%Ox2N`*VVSe&BG&(bVRbMGKt>Q~(r*aVIPWR#@S5S+|i(q4OPeM+iPQ?TF0DXcu!Y0!VmNuCEG1)6pHlUK0MTSe5ZT+`Zuu9E6_!d z{-+r#fYYRofSMmKCKHBZT4k8awzH=UpGx-z8as`XK{B)!o5kM1ED#@*NH9($q*t;( zOEI=_YBath*2zWGc zQjdq5v1E&zsqH%kqjTpHr6NJ5&4)-#pq&^i3Xv~h8c?JV1;=tk6(N8u=A|P9D2WBr zO4W->&YMrULJu|6xr$=)O4rWEv@TSPSpAS42{b+%G(#0zRpj%`i&E)LedBBwDP4;|Na(N<={KG+4H~X zdh=)~+`s=nvX`twr7VM(A>wV{hZ&8*7&Aj;E2W}PB9Se7gR;z^Y?F+ck%U5aiDHDZ zL?kVSkYvlA@8xs<&VAqC&-e2?r_&#GIH%@vU9aW&d_0poU?Jb%KMA?|(Gsh85C#|# zmG;EHFJGRkzxn%ijF94D)Hf~%Qxg1Miso3OkSB?mL={kg@N*9`a%WE3L9Do;2<^+u z;tSCwi6!h~RpzV!#078xNPx#&pZfxszo%mWuo&ib2dszaEv!rc2*^?~Xbk1K03;T7 z`#Y3-OOmsWo`1p*-@|-}3y5X#-BIW?|NX6##YoK0_ACL@6RtsBqLzjmm&JI}b_D6f zK#29tBakDT%=x$K=fHNk-pDm_Wc8MR=&iaBf1Y-dab$wD>*zJ#zosi2NwW$lNZCCn zp~-7wZB;r?N0E9o-!sOa;!EwGZf?bR@~IX)y0U3cREUi4Cy_T+YV3qH;&i`hf47A> zqOa|T?_&e&ftC*`V8%$DK3rw@X1DuJB_uy+H5uaqebABpZgKX&?SJN>Q5W+@F4Osp zmg6(l!>7=aSUssrwQHN-%(< zPz?mk76X16Ua%8(hDIhaEwQzKT>M@E72o*XeZSumB%Uu^*(_TZ1Fo#%#)NgM;K4ge z%*(UhZXWl7Kn{1FipM`$1bG0^u5|BW@?LL%A+1sC*NZ=fM*RF>C;@$#D0%v4&lFp{ zB4~*B#)wY_ClYerURwFnjq6>|PV?JwXt)SkKt6ZIWmU^Iq(k!I`47&qYp%icDap=iYfgJ?NaJA`Wk!~ElT%d;LAx4>yPK$@GOyf(JGOb>WbYrb zbofq2wv>w~f}%IIZ~kYGE!i?dC;QzVmM2`-FLmR!?YxIBXphRnPt60wtPH*y~^AjTM%qkBlUUV@DH2EwS2Q#0S(= zK%^_;XldhYj_`^jrs^s%Km~2T3gX0X%Z8HPDge@56O`VutFaH!*H&PF?#J;wIGo^@ zgn?P80$tcxTO3i9T|oy*Cw_$iVZfp?MsSxMp(~knlq5?^gKi3y?kS!q7z2@(vrJXx zv9#+JI4>UCZ>~r|Guuqn@Yu7akLDFOq{H$j=;x%4n(FubH9Vm;4#3Na4}*S~?6m8y zk}p?e;Ue;fg6|K7xle`6{gs&>NxrQ3^xg}<@1dQSe>8uNsN+-oDBT}8S2N2FDp-w@ zXf*xt=K{y*T0-ExXtGb+fYRrg38D(Ep%l2rp^SGlb(-YS#_%-4sk}-ii@9w*WTFD@ zN?8!)>Z_Xu9`!H=z}U2BQ0&NrJQV!nA2ogmj^+?;opGS|K2qb!DI06f;)vmURG7R(P^IrBman>5h`XyP;MLof5ZDqmIX&6H@ z<-rxaaK-G=5505IPzDhX(V&Ige4Ni$@?4cm%48oj_r_SUI`vOm)46(n0cDt-mvYv& z)d`t5$ilAWwGPcYi|c~bFJD`VNm+rULfps5@pzsONQ>7A5iX(rH!F5ZA9C0q7CT8U z69&^cimuEG7-q8VF>Ir`zgZnZvg>k1MkkcRZVLBl$r${W#qXLK2>-Xbw|M!bRpP}j@TLZfF|P291@!@HK&UER}tE(jn{ z(a1`v_W5X=G#m~n@|+e#MD7RyCzP3j$`yAZ^Z_Mf9*s(G4Wy`mnVuk9gW9A<}(BRsD-|5WLDvz+r{_H_+pfruXZ zy>p>>Nk;I+uOWt$3O#kv;O=ZyA|p_+dI;<4ukpfQW?(j=@$dD<wjIK4OOY%ygVM{5qUO*F#iAXvyW(V z?=FSXPzTiMd)Q)LqSRP;fQl^vNeL2G0>}R6hH~+PMA$A<8&p&G@}Xp+j@_bMaW+q3 z$l?m%97vmi8eg> z;&ODo(u<3+x0GJ^$8IX!Gy`BueNd!AN~wkAq?sqPTki?^@8+I6NDvdX3OhKQ-{F2O zD<0rZ;Vn#jZ`;THG?59XJ4r%Gqm`A)PffFQMTjklFkHRNq*}D0`g^}%M-xTaRAdp& ztNfl*jU(7L~f*=2ePf085A5%0uwk|IzZU)`jN?`IN)H z&$Z5p6}`3^xS7V2EJm!hZ;kJK3ZoN2G=#vemQ(cSVgfHj%BnpJIc{PBfw-8%d{3&B*Ya=u`*Vf<|{lU51yM)^zJezr1 zMJrleq4>NCc7=={@3pexah&`EbY1>MIn+#nV1Tb(h$HslfhFbatBr3~4n=Z(F-V>b zs-2u&k?v=xdvnfSn&&1>qJHP&Q+-c#&u-`VA05wIt^lC4n0w8NAQ6h0PX)%Z6F^Wr z*fLCzjPy-_(t9?|GYQm`{E~Ba08$Y!6Q6NFkS$I{!dnwPt!Scb@!7;&O(=g@7g@f$ z%lmw0+8HvTRE3dS*?Jjh8406L?xlgI)xpYvP0TsPhlJFxIDZ^Sip9*)WITSuU>1$& zOCQ-+TpkOQ^aAcl5$B>!gaQ+ZJ!CbQSTf+ZlrAu*r_MNRdY-C%{4kgk?`!i>eM}d`Juv^T3iiLp{r~l+&LHFJ!se=s^3>b= zOYfeUSi`!o09iNoLH4}BVc2nGxIt$b?pUgg>vrH2eAP%|lI8l9tE(TZSD7r%j ze~4942G7)V#PBOy<8arUuf!}Sc3qRHEGk*4we`$8NeVv}QV<}p5MP$`)V)$&_X-ni9y6koJx4ruw*3_b zdoKX+5s*dMttbpeQD>~c)XCYB8{(7?{7j_*K8SxwoHSt!HSY!B!vnHWOB{%sTQ;-P zhgiW6iRZa$*eKIgPdP&62Fu~!QGAILv0i9T+*K_-eo+kUq(c4$RGSz+FaCU`ISabT zKfNb1(gFj}NKp?sHQ}ti?1L(QUW{rMKYHU>F^=FGnr%)pFHh#~`j*>T`yhgMXXE0< zDlns%)uoBmwc2AuEO8ZT^Be(Vx_tseL9Sgpif;1@^q9uKL({GvzqsMm6DG2&(P5@v z8abYe!sAyVWlQm5LJ+WhCk6N*ai~hrH$s`8)(8b5w|47;t?14l|C*lGOTTwjk~tQD z;j!?C(o0l9hEu12qEcES`H{P`+U*rd4emg<8{u%Ugd@rq9|SN)lw4$0Pl`hE>xzKYH?PpopHO8m7bjD)?pDYVm~aox29`_ z;tTJH$rgnvdiq$cJ{Zd+$K$Wo}C z4j>sS(^;J`0C7|gg@4_Ju>1q!wE*-=`;akrkN<)v2+}|SYBh1Ujy<-!Cv`$E4>(CS zw}ZnfP|`NDd{yWJ5_cP+(LNwdf))0)o}+bm{$5lNhu%Tk@DH7bu4|#}%;oN_X##I< z*=$|&KLG+~aDnQ160MO|1;-6Oi;z#9i)KkLMLU-{d%#u3x#^V82I6W-OI%ZmJ^jl$ zqIV`VD*3m@g6)93%G|2GuH%*V(b<;`6o(g0-wphqZn7g%`&@NTV!xW09RfguFr@ep z;RAEHH|Ew5h!7w^yMT%lD7JC-cztKcNu0y3UgV#{#zCKXIA7l@qAs4ZbGtRO4~6}g z5D&n6q4u$4(N26}PI78x*zC{a_(piqmGh37XB@D%EwR_e_{-FTXRo_$a_YDHh3kZZ z)knS~eh{P_L33tYHcQWgy04q-#5R3O-5%j3U*?mOw2}lIIe=`Rfdc&~5*KcA>ywk6DDOC%Q*b?V7MtXSEa_L`NryT)_(sz8;L?9=!OvR39W1KRguO?C)7bYC_^hd285TF?VT89xjTFp@=rbdGHIHSeTMu*$+-% z0g&2**tSpI{;z+4N6_G@Ffe>P1}N$ogcwn>TNWe`5%x(Cvo7p5Qwoe0mW={UU?WNh zia=ceN-+^a3s%Zp14T4*D*cjJ)UJAy18SD6XAZP@Of!SyNJj|J7z=fYqm>Gj*4sLm zabS4<`~KC2?TUP;LAAx2m!bi-dFsbz;)k#85+80~NB4F&uf3K|X@fC{g;!b6hr;)@ zQwI9UvtKI%y6yUnnZ!1HlMH%{JVg_SiPSh1j9pCf%ZMy-jr{fy1pp-^fQn^?X#wql zfdu#s$|xx^Ummz$u>Kun(Bw5R1LqB8-UEc60`MlzPnVen4gE3*u>i?iKl&sE6WtZk z`Y;M9S2UsUZ=)CI#>DXXdb>pG+jTt}`u~!IO9-GOxE;cQ&-1~Flr3l}5gR^V+Bl=h zJTUW7C(AcD1mSRX358QUj9~Lx1xK?cL-g6Bfznd;z~R9UWFkRT;gb8{zEg)d2Ki{Q z5Zk8Y$~&6O0o$vM)lKMQPoy*)d0yn#tKYJHomleU`1Cvf6W;PKndpbh`YWv=PWrC@%z5Gq{z}Do&=EG{#=PAN1DCd%OP!f;$8xm z3DOC7H$lh*EvvpG_SqyB_&D)hNK3gYJ$r5-QP7eGrH`f}qmT~{ac~FGgW53W-%8C} zAkh^>0&sSz7$evqCrIwQ9T1ou1QX96YlMeInqWw80~YtistSz3_0)izH*OO-GSDiudbR?lQZ)&xVQsWLsKw~xLam-3!kj+k+R=czJDkt z#C59H4{KdAI-#Wi$*fxC1VKcf3>UYLnXPi{P1)(L!T$KoqX$fKAR!lZ5TTg89>F#E zVi)Tk{x@$d1hH!Jb5yX8*4xP>JDwE>v3F@DdYVvyqL9v^Y5%-uG%#F2W=bux0`|PJ(mVaK~+tvPyPh*%T9bPqcWwgig%`@MVh{4O>wLMF!=M@HZ z+~w(eCd3GZ?8Z=jmAu%?CAo`TYoQjRB(J7VJ)1!wC-r}1OaFHS*6uv23SwOK(eV40 ze$u&DV>8Pi_8C=!W&K6BbM=z`!?Na>+X^FI{I4JNX)u#jf%}TU9w>J9gfW_@Zd5q6 zhL+pZ8@Hq3QYdZiAz%3?S5{3(u!)DN>RE3xTc0QDc4w><8K7+Da@z+U@9GdZJwkUL z=ftPS?fm^Z-qM%--g19=illc7TE5t~;mpXSy;FtAtN4A2gU$8R2So_UAf$EIr745m zGnKZ;!6|e!GZO9%7lS#}UmE63Q+@ba!NFRdo^1ef{}vAt+xSY*SV5FMH|Pc+C!$Nx zC1~6sD=?%yD!*%dA4He1h0>{2;6p-|55d^R)uIEGn{ki z*fuE_18S0VR#WZ#KfpVf{-|bN%{VmSS8i`Jp>Fl;e!%-g;M}gW_IZ^urDW+R4%Xe6 zRf#ElY{q(T?I3)1M4$*xuhe2`mP~S>X{P$ud*Q`_WA{~QK2683N0VlWyS@CKe9d%{ z+hzkb`s!j|CzM?sfr-5OSrlf$PB>M8(&ta?M3Gr&S&t5phhPXm5a!BP#W4 zse8)EsOOw~*$bfA?+Fu0^S3CMPk712kwfU%w|*aa@1HQZJg$eX}^i=w$l7 zrG9N?Fg+e;L&Jo!8_Xn=^cDhqCPs|Vb~o=2%Z?SoE0 ze0PNl0`d&y0bhWY?gI}MnBap;qO=tNAY$+bOc)K*ybJ;wcG(U9%wvapaxj(9!Vl{L zwx!$F@Lfhp@ef#KC9v9`sS5ca;|acj8B#;Awz8eXE0-#kiO{Ir15#Vd{Ja$gxKeG& zpc)L};Km%9)Q-Da8Kg=xlqnWF=szQq8$~iZYIZ*^=!@aR!ri+IBP|j1jPY8{>H|?r zto(axZnW_{S9<@-3$#M;@fs%>_l#3)gXBP+D{mjPzHei$`i1Y-+1t-Q$>W=vC4mQt znLC?OZCxJu!rx0jC~Q?1&Mal{Jz@mb-6_%(A)Z||>3~^1&NWzi7WpY}yEYgsp+0ID z-Z%vk0@laIQar|O>kfZ51H^^)Yjk0KlztJoWS{kiksg6_o-K;tmID$?|LMoym@K6U zd7q@Evq#fsGJOy2#(7H}$tT%imqQ;{Q{kb66w4NACV&FmD%wj3z@ual$ zg*xgvFPxv!FQz=TOGEK{Jq)a5Yx)7svWQA9n-3D(LQ=JoYMfIz!Rp>^kr#x=XtJK@g?Pz+NS$(&X!X0rz9M-zj zcImW~M(sl1f%LzM-ak6@9GKWl=Sy2*CRva2F)E`kZd1+WKU-oKIFQolP$3SbtT4l4 zl&yctgbqO;{(kqcfBj_}*&bU9n1CnkR)EbJ+7Ajmrr%>H1cU@LG!{m2!@xkr5|;;I z!8COaK#GX+C4c*@ODfbN;4}~g3)M$i$}=3nn(PaxG$wzA+dLr$0Qo84tb+YNSk^k` z@a`mn{Q~4wtfzqM$8X%RUlih|5D?;*8H_?9PwlbdG$K6b@N3q7al#iFztV5s!UOiD z<*kcrYCjk9<9^it9-e<6ITSOl3k>BSVy=^>M?|OIG2u*$PYh(QA#P*wc87kGB zbPI&%@qfDfgbFVdV3hg*>OV+u*?qZoqqr}IO9Ye%l;jX{=1GrC-?>G8lS5&zod^Wb zN?^BxvK~TH_v`qu1mtZ9%9IT?O%nTuW#Tp3;xOLt(1-rI8)udQt|-3<6c4F3wpiodqMJ!a!s(7U$hA1FqnBR}!U8a(4pC`@qBLSe1R4h>;c+49CA%~2 z4j6tUcwGq10ut8TTyqRR2yEQtQx}(K=nYW1C6~j~x1DgIrTN+` zPB_&6pUes#N_ADvc|x~8I%^YrE>k2O@E&XtMd8dh8@QfJ$FErP_~?E~iB@*0PPu!MHv4=yyla#hZ3Xg_%!4q}1>NMznLa&KsMX5{#Ki=5EW;}CME-u%ti2zFi{WX-)LZm+)*0e@x?neEr%R2EYo;0iskD5Pb^y^vr-AFCp<{|Fz z@x4@&Ka?ryUI(OP@wjuX+N|~=ob1O$gnNAKT+N1PWJpN9s6(@O&j`i;HDi^=o*>*8?LInZ@&e?kD z$Gv<9R?LcOCk5GUqw2lfES>;{3~=|Eux(28V& z#n`413d`Yp5A==0)oy-teFV){M}>j3{OGMaZiz(&z^4QUXFFlK>Ooza30Ye(gyOJf z-XA=xwJul)REhu5v{##pd0W3?eA5hjJmjRS&OVo?FDtKqII81vukNyRcF#wzUk#hD zl%~KFIyPyEV`fLoev{f(PDJu44lDNF;GWQPa3?}SiV_c|vvnc0gMR*xTJNS8j-I_+ z=rgn#1{1qeHTc@AxjaG!ucj`oMH3yK1;)FJg(rqDSOvp_uuSHzC z^rZ(0`|;9IYq<1w@vkvx1$r?+N}%BoT=#RUBH(-{CAexvLj+6DJA|5tXT=#Kond>i+1w8{{8MR8)Azyn?~xKP_GsKZ9*t^DgB{ zxC95C{#;O?7rbDIY5u2HO-dgL7-9myH?TKl(BfYo^(FKR6B}Mja!`to2ly+Gb_dnE z*$izW8r5Y{6XJDzBjGK7W~%QGji0)YE#TOMd%_nAb|zkE@;F4~co<0!w!SVX0frgE z9VzT+)h>b^SAM&f-dd`Bf zT7-xMdO=DNLY$HiAh5O(a=%f``8?3}VM{5fkJr!d#%j(~>|yN{2Er45P8f^xb%{eO%tekG0I_{!A&U5O)1K?jv-YI|hl#roBbs4;Vqp`*{HTaod_&k>peG?DejD*y5{#Qe zJeUfdt4k|P{(kXJ5vF6q0auYDO(2!S`%9?NW?h~tLvgvSdu9&WYW66R^^1%7LqQ0?=O8CX|wRv zT>8YK#p{EM)O2YaSdpHrmEvs^^P(8#X0JQih)5c~AR*)TFt&m^ba*@4yLGhhU(fs~# zFXzt@S*$O?zdk_1hivnn@2`HfRG}Z-UmLbV8*47UEViSyry(K(bPT`v8e|kA+%DBe zojX)!@oR7ThqGQ z0P&Ct-%Vh4)?ewY(T*Ow5Wl9R<;9xVVVza zOK@2^dB><=DeM-@(k{fx>*eU4TVP>iN4w#mLN`%z+fq=3Ke{qxnno}i33MQS)HysF zxYqw3#3Wy%D^p7oJ)4g6CgxXicD8C1W5|>YXGff~Y_US40lj;Jh^sIX$C)V-oGg)O z2MsS2(8Em|Dh1!YI>Z%hceR&q6?=7@Z`JO1RORR0m@(}%;*thk+EvGVwQ1S-xFzoF zN99O>niLCUFNGxLk4(n(I^_5JZbwgvTRndzA$4c#tibwnc5$yn+PT|b5P3&y7+s0V znxctNzLhLrw|4PKnk$Iqdsuz|tr@7x1!V^2#cJ*klKU|6BnJK*rv|k_W&G~Tg%+eg zCaI07yT!jJ^eJB5>;@rFKcLF#m^X#M5m97bkM%OAtQi1{2T+bPP0>si-HHR3cXOfuO`TSgn(*3gSzqTtL_@dj)bWULK|WX37)^c z8*WtD0API{1~Bc6U2AIEE{GB!vSmey=XTu#6E8{B)5h}8_&|lL3U#)3q5wgxvx`0P z%ga=Pg$R+bpTA_sVBm>AXT*4SaN6B#LM~;oM+@|IHop|2+7y<7Qe-&P*$80C7hz{-muEltMWisI zT`Q*#!XH6#CRqeApws$q$0G7cYT+Ky}>@Bn-Aow7rmc<&&#FtN6}Vjk0TECg(FT#JYM%lJXUEt6%b!!Q(4 zxD-3BYUIi_n4NoC-pZ>82%JoMzqgC8ZA!U7MIbM)%WkRd|Fg-t7V+jhJC(}m)i`}? ze?^d}lVy+ftsb~hLI3>iNZBu;$(OHZVlv@DSHq_osWk8z7H4yQT^VngjjZL>(`VD| zg*Fvd^Ph+Rk|d~5Uz<(zEy#qNn|$@)m@*@Pi;@P`1fgS_uHwLX5}jMO7%Lf=CB5+3 z2?WP|drl#U2ou5Z`6CiwFPZsa8<+AgHmN*a`L=GOS{MZkfM9Qbo*>k_gI(A zdm9HXJPRNtW@EHMWQB9!^WyA&V0kQocI|`97lbuY>{607`*WM8Do^cX zb}*m)yY&B+h%vgyIXLxK`1CDK>(8In#|=7MhK6Te_dMAg%h_5Hjz;;Q-bY zgCsb%%SdK_VSgASB}nKj5=7?>!CyeO^oQ4TFpV&o>04oWG6BmN7r z-f?>VTX2Z&DfK<-%0?*5gH|FK*gY}4L@dG;wUsmp$vpCZ%L}D)+&F>Rj zOt5SUJ|i7;O`S1&r)=AS2tjBcdn`V2y&!dDQ)nsM^7peNt6y~mfbL;)*Hmk17hcGz z0iNaE|C+|edi|=omxFJPDg+2zl?`mISw>(Vx_Bti%*3=og7IPe7^4Yd zhmT7<%`cMFJ(W!i|2iN5?>YBnb-tjnh}mUes&{KPLbCaK^{cSjm~`AT+WRy2geVUVoW*&Jrz`>LDv{`$g2T1706(BG7#!zO=a^!M*~*-f{; zv~^0qeF0?_amh+ZVPx%|G&0Jl=!MbdRlKy>VGSDNW;A(*!s|KHytx46SP%sF!bH?f zAFj;y0hpc!SSz%w5llh_yrrxLC5b2^lNz0USe$syp7363GZYXdo-R*_x}cTn)EeB0TYU_LcI9%!>V?`LqjCH$*D*b5`M98SM}n!)+jPg1K8(6{1= ze^zT8*JHz5pMOfozSt+t{45AmfV-#mJYq%8b~i=ZVK;MAjkLR`rK_3x5kv?>c@3p$ zgii@lc0KP22X6_$c+8vi&&Cmt#`u`&!IYI0J>u}nnU>03*(;+fgLRfjM4&eFNfs=6 zrqtj}T}n}%%;glii*&!36g zbcHD}_P@QyiU|E{eHhWMb9z|`I_eG0i@J4P=JpyqsK{NF9#&(FQFiIoJcRI?eDgca z(O4g(4=6H8bReKVtRL4v?qLt`{cqCgx7}lqJ-OxT`os{BBZz17JxNQmP+@{UcJm;m zJLJdNqJfcg!a-qUR?QJ|^=)N1(8sZt3Ka2)l}rq^DcAgb#)P%ATJL(bp}PzTE<)f} zZ#{89Vm0Ag=|@M-{ty@aR)N`;4Oy~YhdwuD&ven=3W9-i8c>!UmD*?T4zzEdEWx_Q z*=nVBwW)ACwK7H7SL>{aZu&^P=wagmQ^2Y~QK z3{E?p_56t{*Z>qYqLQP0imQ^*pF`BABhvq5xNU~|KJPQ>@_lZz{ZASWb4_~ou~${Y zP?eom1{Dv+62&H6rxB1Yy7O<~yJWO#7vGX;%RnH>_y0uC{Id2i&LUX+@A?x=a9Z~D z#lUag2yNlInTj-!B+l|A=bKN6M`e%P;kw~+q)o-kogzkQy*keVU=JGL-@rHrO& zQwY`dNvyN{o)O4o$wnXW(xZl@Hk;_hawTybLmA5p|fp%H}8K! z`SU70F50A`pVk?@ZfkYnltTt6!|DZYfs(;{r!*>{KF9(?>o60Lb@`9wR<&3`nT!+(xclK zAr3EsJB(j`lH8CTPpwYzWzTtTIy+gp{gPSq0_(8#&oLnb-%a*CD5yV@FAD^q{`%F1 zlQB;v5tRO+RfWOdYlOXELAE^LVm%=KVrE#C-V&rF4ISGkGhM)O#8f`Amf^8DIUx?H zKs1*Ea}mnY^+PZyQ^X=1M^D3w+Zi0k3(WQh=>(0{RZ>fsPlg6SsdXrws2}NiK78kA zW8Hji1ugYa@t+4|0#y>>#Z9?_MwMSi6jnHCEpx=N?s;BI9}YhzBn1E=3H$XB3oj5 zaqii5gAeMMDZV>1!)W>{ZJuvjr3mRXT| z4qr940QmXvCjk>gcj+`jFXhMapL>yqqNvf}7J(FB!z0dfdR0)dN$^;6 ziC!k*((f-aCqfwLj^?g^I$(Pc?cPRwprmd=E4MIUBBzQ!?LsD*xdLpUcmtn+C)jqi zN3%MPL9mJrB~d`l^fJ`e8Pvg&MAIiu8jzs*929QlO^$)TUH}WcU4X?w&+H16XYSS& zBE-wup%^b>n<*Nbc5|L&E$bRwN`yHB)hk=b}LD31I76MQ(Up40e1_ zaK2C4uWL!zuFTHX{c8SvB3Y8Sc12I<_jb>s+sFBuVD}#lPrhf}Yx4LuYxz6(+Xnjx zc2s;hSAxF*>hX-fY|QbOf^4vIaYWe1o-qfe;KD2G8$bV!>6YdiRBsB^oX3b$J{y)B zaXTR0BU9Q|+_>!H%VJcsOpyx46`QNxqpnRge%)_24r;`0gJ#Vk_Vt_kM?zg7@wx=8 z8e{<+5-5yVFeJ_`;%D(#_q5aPS*-hrThPzjV*u2j2z=G>nBDO2POWPJn2C(y^r^)= z5DRXlq!-f8ue<2TaO*Ed|xc64P}6A>p~&v6>maY%k{A7=_|u=T%|A_jj{ScgWP$9!$fhmYlQz5t==kRU zp44|ZpW(T5{`9O6=?RpvD77OYh8jfL9op3pg|4UCVUZfmX@u#T;Qv6y5W1z${U>le zhsNu1W@)l?^h#cnx-jL5?}@cqfZkNH-`2leASb6Ci?pN7`(&YV<*kQWLslN_l~FO{ z^IhNiG$xdIv+y7uiDo)2vW2lf1v>n0Ar&Yjc;@vGv@##FTPHMh6$l398uV^=s3C(o zvx(|&ugVCARDrn~rR_4g?0Lo_; zx0YNkYP*&wo47WqqVrD)Sup~4*!H1>tnoW*MxG4V!8ea(T ztlSXk;mGe`fbRv4{6R6|85>+2z!b4?X2)Ye5DNuop%p-KH8y-mu5=|hGqRz=#4RH- zX05DnzRi;+{G}4vBS}zu5wzTN?v#n;v(H@Br+UDHeEVLjwkTQB{sdrnRfmS!tT&ynMqv?%3cauCdpt{7GemO7Zgb4g&{_ z$aFkolV3mRISV#A_%s>C=7Kz;7pg@h=W_y`DCc9@;#gJs@9L&mEDr3tVjk+^F=tns z+yjZ6>&V4i*TRE^sy=Oa*0b5~i z-9TIZKqn{7?o$2sdYt-vCl~<fBm2~%T!CtFS$9qs zlLL^~|1TiskC*Sem{Uc(&buet5Qnt4lnW2vIDjC&o{lT;ZqszcqS)6z7|Sv~Hz&@| z?!Elg&_wUaUL5}Rw#o0|Un{((O}8wf_h#m(4!gyL9I_B_Vl=#iw|Tm{@6YM<_2bKId!-;6hp3Ijn7(3Kqdd|9$` z)s;4JXr3%^AkFR3U-5LdoVi~o?wn08ZPlqbfOK?5tT4AdKCqYrYlo8ZHynH}ZRO0~ zBS$vD=xaERcQ1MecsVgDE*E4D{A~X1h!^Z8?9K|*3*#3z$F{I@f7uDI0(?LKy$IIX z0AXY0ToTjpbz|Ev;*Vei3Mj(=t2EigO&y5$t6%O00jL)a$M}SFsRoc@JxN6g->neb zxv7glxKLgVWvpHGr;*=a_(-sOS-jkd+)9Uy$l^fC`-PP$XT@gsd)`kcKBPiV*@W$1{}f(7)SR?Dx{))V#}JB7=!%hx z?e|brXq2;y3~v83RuVYQKeXwT>3%`^0YW+OFo}weBs1b7%zpHA%@8MbPH{Q3uA;R;`iCjwT$>$A|AOMGJTejF!9Y z*%e<{d1dehbp_o11VX{N9WredwK;tR++&b9ggJLQt5>o#w=jF-30Us?y+f(yo%zUB zf46*;tNvd38?N^;-}CpbgVUVZ5ES!kWqOnI=f)eqs6GBY@-Fl`fAq?p;+HxkkEa*m z0yEv-c?$4?XTK`0Z+spHM?dL1y1TXS_Vw8>&&T8rST+2mzLAto)fu0-kHR1hBhybZeL@9jozW6qpz z6Zgu*D3RwX#x9JxCqC%wfJJXOdopvOPEYxss1{{=x)m6Hfh^9e9JW(w+WIx{!DD#s0 zr*_F5?Bf9W$_duKBu4IGG2)}bnL-=T=!_&&Pd^6T3d&nD|e<)sP#X*z3P <7)msu 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

      dhDKxJ4vC3w8w9R#Q##WZ)~wo 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%0DI9J?C|jPRz_6h%jG_+9aV`CnlC_5#tLs9) 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 S(Eow|eY=rpc 4.0 ) + break; + } + trap.x = m; + resColor = trap; + + return 0.25 * log(m) * sqrt(m) / dz; +} + +// SDF Operators: +float intersection(float d1, float d2) { + return max(d1,d2); +} + +float subtraction( float d1, float d2 ) { + return max(-d1,d2); +} + +float un(float d1, float d2) { + return min(d1,d2); +} + +// Returns transformed point based on rotation and translation matrix of shape +vec3 transform( vec3 point, mat4 trans ) { + //columns of the rotation matrix transpose + vec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]); + vec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]); + vec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]); + + mat3 rotTranspose = mat3(col1, col2, col3); + + vec3 col4 = -1.0*rotTranspose*vec3(trans[3]); + + mat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0)); + + return vec3(newTrans * vec4(point, 1.0)); +} + +float mod(int num1, int num2) +{ + int div = num1/num2; + return float(num1 - div*num2); +} + +// Decide which scene to display (time - dependent) +int sceneNum() +{ + float x = u_time; + float cycle = 124.0; + float fps = 6.0; + float t = mod(x, cycle); + if(t <= 42.0) { return 2; } + else if(t <= 80.0) { return 1; } + else { return 3; } +} + +// Estimate the distance to the objects in the scene depending on the sceneNum() (see above) +float sceneMap( vec3 pos ) { + float t = u_time/4.0; + int sceneNumber = sceneNum(); + + if(sceneNumber == 1) + { + //SCENE 01------------------------------------------------------------ + float dist1; + vec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), u_cwMat), u_northMat); + float bb1 = SDF_Sphere(newPos1, 1.1); + if(bb1 < .015) + { + float power = 10.0; + dist1 = SDF_Mandelbulb(newPos1, power); + } + else + { + dist1 = bb1; + } + + float dist2; + vec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), u_ccwMat), u_eastMat); + float bb2 = SDF_Sphere(newPos2, 1.1); + if(bb2 < .015) + { + float power = 10.0; + dist2 = SDF_Mandelbulb(newPos2, power); + } + else + { + dist2 = bb2; + } + + float dist3; + vec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), u_cwMat), u_westMat); + float bb3 = SDF_Sphere(newPos3, 1.1); + if(bb3 < .015) + { + + float power = 10.0; + dist3 = SDF_Mandelbulb(newPos3, power); + } + else + { + dist3 = bb3; + } + + return un(dist1, un(dist2, dist3)); + } + else if(sceneNumber == 2) + { + //SCENE 02------------------------------------------------------------ + float dist4; + float displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; + vec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), u_rotateY1), u_rotateZ1), u_rotateX1); + float bb4 = SDF_Sphere(newPos4, 1.1); + if(bb4 < .015) + { + float power = 10.0; + dist4 = SDF_Mandelbulb(newPos4, power); + } + else + { + dist4 = bb4; + } + + return dist4; + } + else + { + //SCENE 03------------------------------------------------------------ + float dist5; + vec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), u_rotateY2), u_rotateX2), u_rotateZ2); + float bb5 = SDF_Sphere(newPos5, 1.1); + if(bb5 < .015) + { + float power = 10.0; + dist5 = SDF_Mandelbulb(newPos5, power); + } + else + { + dist5 = bb5; + } + + return dist5; + } +} + +vec3 backgroundColor() { + int sn = sceneNum(); + float darken; + if(sn == 1) + { + darken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0)); + darken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0)); + } + else if(sn == 2) + { + darken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time)); + } + else + { + darken = cos(length(f_uv - vec2(0.5, 0.5))); + darken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5; + } + + darken = clamp(darken, 0.2, 1.0); + + vec3 a = vec3(0.5, 0.5, 0.5); + vec3 b = vec3(0.5, 0.5, 0.5); + vec3 c = vec3(2.0, 1.0, 1.0); + vec3 d = vec3(0.5, 0.2, 0.25); + float t = abs(sin(u_time/12.0)); + vec3 color = a + b*cos(6.28*(c*t + d)); + + return darken*color; +} + +// Compute the normal of an implicit surface using the gradient method +// Note: this method is slightly less accurate than sampling the scene at pos - epsilon, but because that is an expensive operation for the mandelbulb, we avoid it here +vec3 computeNormalFast( vec3 pos ) { + vec2 point = vec2(0.0001, 0.0); + float sampleAtPos = sceneMap(pos); + vec3 normal = normalize( + vec3(sceneMap(pos + point.xyy) - sampleAtPos, + sceneMap(pos + point.yxy) - sampleAtPos, + sceneMap(pos + point.yyx) - sampleAtPos)); + return normal; +} + +// Taken from a presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf +float ComputeAO( vec3 pos, vec3 normal ) { + float tStep = 0.0025; + float diff = 0.0; + float k = 34.0; + for(float i = 1.0; i <= 5.0; i += 1.0) { + vec3 sample = pos + (i * tStep) * normal; + float dist = sceneMap( sample ); + diff += pow(0.5, i) * ((i * tStep) - dist); + } + return 1.0 - clamp(k * diff, 0.0, 0.9); +} + +// Convert a fragment coordinate to normalized device coordinates +vec2 FragCoordToNDC( vec4 fragCoord ) { + return 2.0 * vec2(fragCoord.x / u_resolution.x, + fragCoord.y / u_resolution.y) - 1.0; +} + +// Return the direction of a ray cast through the given point in NDC +// This function includes the implementation of the camera; changes to the camera should be made here +vec3 Raycast( vec2 p_ndc, vec3 cameraPos ) { + + float len = 10.0; + + // Compute camera's frame of reference + vec3 look = normalize(-cameraPos); // Assume we are looking towards (0, 0, 0) + vec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector + vec3 up = normalize(cross(right, look)); + + float tanAlpha = tan(u_fovy / 2.0); + vec3 V = up * len * tanAlpha; + vec3 H = right * len * u_aspect * tanAlpha; + + // Convert x/y components of gl_FragCoord to NDC, then to a world space point + vec3 point_World = p_ndc.x * H + p_ndc.y * V; + + // Return the direction + return normalize(point_World - cameraPos); +} + +// Referencing the following report: http://celarek.at/wp/wp-content/uploads/2014/05/realTimeFractalsReport.pdf +vec3 raymarchScene( vec3 origin, vec3 direction ) { + // Basic Raymarching function: + float t = 0.01; + vec3 result = vec3(0.0); + + for(int i = 1; i <= 250; i++) { + float dist = sceneMap(origin + t * direction); + + if(abs(dist) < 0.0002) { + result = vec3(t, float (i) / 1000.0, 1.0); + break; + } else if(t > T_MAX) { + result = vec3(T_MAX, float (i) / 1000.0, 0.0); + break; + } + + #ifdef SPHERE_TRACING + t += dist; + #else + t += 0.01; + #endif + } + return result; +} + +void main() { + vec3 cameraPos = vec3(-3.5, 0, -3.5); + vec2 point_NDC = FragCoordToNDC(gl_FragCoord); + vec3 direction = Raycast(point_NDC, cameraPos); + + vec3 isect = raymarchScene( cameraPos, direction ); + vec3 isectPos = cameraPos + isect.x * direction; + + if(isect.z > 0.0) { // we did intersect with something + vec3 normal = computeNormalFast( isectPos ); + normal = -normal; + + // Animated color using orbit traps: see the Mandelbulb SDF by IQ above + vec3 trapColor; + + int sn = sceneNum(); + if(sn == 1) + { + trapColor = vec3( + resColor.x-abs(sin((u_time) / 2.0 + isectPos.z) * 0.8), + resColor.y-(cos((u_time) / 8.0 + isectPos.y) * 0.5), + resColor.z+(cos((u_time) / 2.0 - isectPos.x) * 0.2)); + } + else if(sn == 2) + { + trapColor = vec3(resColor) + vec3(0.4); + } + else + { + trapColor = vec3(0.0, resColor.y + 0.4, resColor.z + 0.4); + } + + trapColor.r *= 0.01; + + // Two methods to compute AO: + float ao = ComputeAO(isectPos, normal); + // float fakeAO = 1.0 - clamp(isect.y, 0.0, 0.9); + + gl_FragColor = ao * vec4(trapColor, 1); + // gl_FragColor = fakeAO * vec4(trapColor, 1); + } else { + gl_FragColor = vec4(backgroundColor(), 1); + } +} diff --git a/src/glsl/secondPass-frag.glsl b/src/glsl/secondPass-frag.glsl new file mode 100644 index 00000000..94bfe287 --- /dev/null +++ b/src/glsl/secondPass-frag.glsl @@ -0,0 +1,27 @@ +/* + Code written by Joseph Klinger and Tabatha Hickman + University of Pennsylvania + CIS 700 Instructor: Rachel Hwang + May 2017 +*/ + +#define SPHERE_TRACING true +#define T_MAX 12.0 +// #define MOTION_BLUR true + +varying vec2 f_uv; + +uniform sampler2D u_primaryRayPass; +uniform sampler2D u_previousFrame; + +// The sole purpose of this pass is to compute motion blur between the current and previous frames +void main() { + #ifdef MOTION_BLUR + for(float w = 0.0; w <= 1.0; w += 0.2) { + gl_FragColor += (1.0 - w) * texture2D(u_primaryRayPass, f_uv) + w * texture2D(u_previousFrame, f_uv); + } + gl_FragColor /= 1.0 / 0.2; // divide by the number of samples (1 / stepSize) + #else + gl_FragColor = texture2D(u_primaryRayPass, f_uv); + #endif +} diff --git a/src/glsl/thirdPass-frag.glsl b/src/glsl/thirdPass-frag.glsl new file mode 100644 index 00000000..9f5ecbee --- /dev/null +++ b/src/glsl/thirdPass-frag.glsl @@ -0,0 +1,14 @@ +/* + Code written by Joseph Klinger and Tabatha Hickman + University of Pennsylvania + CIS 700 Instructor: Rachel Hwang + May 2017 +*/ + +varying vec2 f_uv; + +uniform sampler2D u_input; + +void main() { + gl_FragColor = texture2D(u_input, f_uv); +} From 9d66fd6213919f5077ebccf006424274182370af Mon Sep 17 00:00:00 2001 From: Joe Klinger Date: Tue, 2 May 2017 23:28:40 -0400 Subject: [PATCH 16/20] Jorb's actually done now --- build/bundle.js | 24 +++++++++++++++++++++--- build/bundle.js.map | 2 +- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/build/bundle.js b/build/bundle.js index a7e03530..cd4e9f46 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -69,6 +69,14 @@ var THREE = __webpack_require__(6); var OrbitControls = __webpack_require__(17)(THREE); + //Audio and Audio Analysis variables + + //Create an AudioListener and add it to the camera + var listener = new THREE.AudioListener(); + + // create a global audio source + var sound = new THREE.PositionalAudio(listener); + var BoxGeometry = new THREE.BoxGeometry(1, 1, 1); var SphereGeometry = new THREE.SphereGeometry(1, 32, 32); var ConeGeometry = new THREE.ConeGeometry(1, 1); @@ -98,19 +106,29 @@ controls.zoomSpeed = 1.0; controls.panSpeed = 2.0; + var audioLoader = new THREE.AudioLoader(); + + //Load a sound and set it as the Audio object's buffer + audioLoader.load('Dubstep_Sub-Mix_2016.mp3', function (buffer) { + sound.setBuffer(buffer); + sound.setLoop(true); + sound.setVolume(1.0); + sound.play(); + }); + window.addEventListener('resize', function () { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); - var gui = new _datGui2.default.GUI(); + // var gui = new DAT.GUI(); var options = { strategy: 'Ray Marching' }; - gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']); + // gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']); scene.add(new THREE.AxisHelper(20)); scene.add(new THREE.DirectionalLight(0xffffff, 1)); @@ -48470,7 +48488,7 @@ /* 15 */ /***/ (function(module, exports) { - module.exports = "\r\n#define MAX_GEOMETRY_COUNT 100\r\n#define SPHERE_TRACING true\r\n#define T_MAX 8.0\r\n\r\n/* This is how I'm packing the data\r\nstruct geometry_t {\r\n vec3 position;\r\n float type;\r\n};\r\n*/\r\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\r\n// uniform int u_count;\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\nvec4 resColor;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t *****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\n//diagonal is the vector from the center of the box to the first quadrant corner\r\nfloat boxSDF(vec3 point, vec3 diagonal) {\r\n\tvec3 d = abs(point) - diagonal;\r\n \treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\r\n}\r\n\r\nfloat SDF_Mandlebulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i=0; i<4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n resColor = trap;\r\n\r\n return 0.25*log(m)*sqrt(m)/dz;\r\n}\r\n\r\n//Operators:\r\n\r\nfloat intersection(float d1, float d2)\r\n{\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 )\r\n{\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2)\r\n{\r\n return min(d1,d2);\r\n}\r\n\r\n// Returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform(vec3 point, mat4 trans)\r\n{\r\n\t// Columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\n// Return the distance of the closest object in the scene\r\nfloat sceneMap( vec3 pos ) {\r\n\treturn SDF_Sphere( pos, 1.0 );\r\n}\r\n\r\nfloat mod(int num1, int num2)\r\n{\r\n\tint div = num1/num2;\r\n\treturn float(num1 - div*num2);\r\n}\r\n\r\nint sceneNum()\r\n{\r\n\tfloat x = u_time;\r\n\tfloat cycle = 90.0;// * 20.0;\r\n\tfloat t = (mod(x, cycle)/cycle) * 3.0;\r\n\tif(t <= 1.0) { return 2; }\r\n\telse if(t <= 2.0) { return 1; }\r\n\telse { return 3; }\r\n}\r\n\r\nfloat sceneMap2( vec3 pos ){\r\n\r\n\tfloat t = u_time/4.0;\r\n\tint sceneNumber = sceneNum();\r\n\r\n\tfloat angle = 2.0*t/(2.0*3.1415);\r\n\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\r\n\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\r\n\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\r\n\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\r\n\r\n\tmat4 northMat = mat4(1.0); \r\n\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\r\n\tmat4 southMat = mat4(1.0); \r\n\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\r\n\tmat4 westMat = mat4(1.0); \r\n\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\r\n\tmat4 eastMat = mat4(1.0); \r\n\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\r\n\r\n\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\r\n\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\r\n\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\r\n\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\r\n\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\r\n\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\r\n\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\r\n\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\r\n\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\r\n\r\n\tif(sceneNumber == 1)\r\n\t{\r\n\t\t//SCENE 01------------------------------------------------------------\r\n\t\tfloat dist1;\r\n\t\t//vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat);\r\n\t\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), cwMat), northMat);\t\r\n\t\tfloat bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1));\r\n\t\tif(bb1 < .015)\r\n\t\t{\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist1 = SDF_Mandlebulb(newPos1, power);\r\n\t\t}\t\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist1 = bb1;\r\n\t\t}\r\n\r\n\t\tfloat dist2;\r\n\t\t//vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat);\r\n\t\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), ccwMat), eastMat);\t\r\n\t\tfloat bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1));\r\n\t\tif(bb2 < .015)\r\n\t\t{\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist2 = SDF_Mandlebulb(newPos2, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist2 = bb2;\r\n\t\t}\r\n\r\n\t\tfloat dist3;\r\n\t\t// vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat);\r\n\t\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -0.5*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat);\t\r\n\t\tfloat bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb3 < .015)\r\n\t\t{\r\n\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist3 = SDF_Mandlebulb(newPos3, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist3 = bb3;\r\n\t\t}\r\n\r\n\t\treturn un(dist1, un(dist2, dist3));\r\n\t}\r\n\telse if(sceneNumber == 2)\r\n\t{\r\n\t\t//SCENE 02------------------------------------------------------------\r\n\t\tfloat dist4;\r\n\t\tmat4 rotateX = mat4(1.0); rotateX[1][1] = 0.0; rotateX[1][2] = 1.0; rotateX[2][1] = -1.0; rotateX[2][2] = 0.0; //rotate 90 degress about x-axis\r\n\t\tfloat angY = 45.0*3.1415/180.0;\r\n\t\tmat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis\r\n\t\tfloat angZ = (2.0*u_time)*3.1415/180.0;\r\n\t\tmat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis\r\n\t\tfloat displace = mod(u_time, 90.0)/30.0*3.0; \r\n\t\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX);\t\r\n\t\tfloat bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb4 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist4 = SDF_Mandlebulb(newPos4, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist4 = bb4;\r\n\t\t}\r\n\r\n\t\treturn dist4;\r\n\t}\r\n\telse \r\n\t{\r\n\t\t//SCENE 03------------------------------------------------------------\r\n\t\tfloat dist5;\r\n\t\tmat4 rotateX2 = mat4(1.0); rotateX2[1][1] = 0.0; rotateX2[1][2] = 1.0; rotateX2[2][1] = -1.0; rotateX2[2][2] = 0.0; //rotate 90 degress about x-axis\r\n\t\tfloat angY2 = -45.0*3.1415/180.0;\r\n\t\tmat4 rotateY2 = mat4(1.0); rotateY2[0][0] = cos(angY2); rotateY2[0][2] = -sin(angY2); rotateY2[2][0] = sin(angY2); rotateY2[2][2] = cos(angY2); //rotate 45 degrees about y-axis\r\n\t\tfloat angZ2 = (2.0*u_time)*3.1415/180.0;\r\n\t\tmat4 rotateZ2 = mat4(1.0); rotateZ2[0][0] = cos(angZ2); rotateZ2[0][2] = -sin(angZ2); rotateZ2[2][0] = sin(angZ2); rotateZ2[2][2] = cos(angZ2); //spin about y-axis\r\n\t\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), rotateY2), rotateX2), rotateZ2);\t\r\n\t\tfloat bb5 = SDF_Sphere(newPos5, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb5 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist5 = SDF_Mandlebulb(newPos5, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist5 = bb5;\r\n\t\t}\r\n\r\n\t\treturn dist5;\r\n\t}\r\n\t\r\n\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\r\n\t//return dist3;\r\n\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\nvec3 computeNormal( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\r\n\t\t\t\t\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\r\n\t\t\t\t\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\r\n\treturn normal;\r\n}\r\n\r\n// Check for intersection with the scene for increasing t-values\r\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\r\n\tfloat dist;\r\n\tfloat t = 0.01;\r\n\tfor(int i = 0; i < 500; i++) {\r\n\t\tfloat dist = sceneMap2(origin + t * direction);\r\n\t\tif(dist < 0.0001) {\r\n\t\t\treturn vec2(t, 1.0); // intersection\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn vec2(0.0, -1.0); // no intersection\r\n}\r\n\r\n\r\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\r\n\tfloat dot = dot(normalize(toCam + toLight), normal);\r\n\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\r\n}\r\n\r\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\r\nfloat ComputeAO( vec3 pos, vec3 normal ) {\r\n\tfloat tStep = 0.0025;\r\n\tfloat t = 0.0;\r\n\tfloat ao = 1.0;\r\n\tfloat diff = 0.0;\r\n\tfloat k = 72.0;\r\n\tfor(int i = 0; i < 5; i++) {\r\n\t\tvec3 sample = pos + t * normal;\r\n\t\tfloat dist = sceneMap2( sample );\r\n\t\tdiff += pow(0.5, float (i)) * (t - dist);\r\n\t\tt += tStep;\r\n\t}\r\n\tao -= clamp(k * diff, 0.0, 1.0);\r\n\treturn ao;\r\n}\r\n\r\n\r\nvec3 backgroundColor()\r\n{\r\n\tint sn = sceneNum();\r\n\tfloat darken; \r\n\tif(sn == 1)\r\n\t{\r\n\t\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\r\n\t\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\r\n\t}\r\n\telse if(sn == 2)\r\n\t{\r\n\t\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\r\n\t\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\r\n\t}\r\n\t\r\n\tdarken = clamp(darken, 0.2, 1.0);\r\n\r\n\tvec3 a = vec3(0.5, 0.5, 0.5);\r\n\tvec3 b = vec3(0.5, 0.5, 0.5);\r\n\tvec3 c = vec3(2.0, 1.0, 1.0);\r\n\tvec3 d = vec3(0.5, 0.2, 0.25);\r\n\tfloat t = abs(sin(u_time/12.0));\r\n\tvec3 color = a + b*cos(6.28*(c*t + d));\r\n\r\n\treturn darken*color;\r\n}\r\n\r\n\r\nvoid main() {\r\n\t\r\n\t/** Raycasting **/\r\n\t\r\n\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\r\n\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\r\n\t\t\t\t\t\t\t\tgl_FragCoord.y / u_resolution.y) - 1.0;\r\n\r\n\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\r\n\t//vec3 cameraPos = vec3(1, -4, 2);\r\n\t//vec3 cameraPos = vec3(1, 0, 1);\r\n\t\r\n\t// Circle the origin (0, 0, 0)\r\n\t// cameraPos.x = sin(u_time) * 10.0;\r\n\t// cameraPos.z = cos(u_time) * 10.0;\r\n\t\r\n\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\r\n\t\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos);\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\r\n\t\r\n\t// Perform the raymarch\r\n\tvec3 direction = normalize(point_World - cameraPos);\r\n\tvec2 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\t/** Shading and lighting **/\r\n\t\r\n\tif(isect.y > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormal( isectPos );\r\n\t\t\r\n\t\t// Lighting\r\n\t\tvec3 baseMaterial = vec3(0.1, 0.2, 0.2);\r\n\t\tvec3 trapColor;\r\n\t\tint sn = sceneNum();\r\n\t\tif(sn == 1)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(\r\n\t\t\t\tresColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.8), \r\n\t\t\t\tresColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), \r\n\t\t\t\tresColor.z+(cos((u_time)/2.0-isectPos.x)*0.2));\r\n\t\t}\r\n\t\telse if(sn == 2)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(resColor) + vec3(0.4);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\ttrapColor = vec3(0.0, resColor.y+0.4, resColor.z+0.4);\r\n\t\t}\r\n\t\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\r\n\t\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\r\n\t\t\r\n\t\tvec3 toSun = normalize(sunPos - isectPos);\r\n\t\t\r\n\t\tnormal = -normal;\r\n\t\t\r\n\t\t// Visibility test\r\n\t\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\r\n\t\t// float vis = 1.0;\r\n\t\t\r\n\t\t// if(shadowTest.y > 0.0) { // something is blocking this point\r\n\t\t// \tvis = 0.0;\r\n\t\t// }\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t// Phong-ish shading for now\r\n\t\tfloat spec = SpecHighlight( -look, toSun, normal);\r\n\t\t\r\n\t\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\r\n\t\tfloat ao = ComputeAO(isectPos, normal);\r\n\t\t\r\n\t\t// Apply lambertian shading - for now\r\n\t\t\r\n\t\t//gl_FragColor = ao*vec4(baseMaterial, 1.0);\r\n\t\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\r\n\t\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\r\n\t} else {\r\n\t\t// Background color\r\n\t\tgl_FragColor = vec4(backgroundColor(), 1);\r\n\t}\r\n}\r\n" + module.exports = "\r\n#define MAX_GEOMETRY_COUNT 100\r\n#define SPHERE_TRACING true\r\n#define T_MAX 10.0\r\n\r\n/* This is how I'm packing the data\r\nstruct geometry_t {\r\n vec3 position;\r\n float type;\r\n};\r\n*/\r\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\r\n// uniform int u_count;\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\nvec4 resColor;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t *****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\n//diagonal is the vector from the center of the box to the first quadrant corner\r\nfloat boxSDF(vec3 point, vec3 diagonal) {\r\n\tvec3 d = abs(point) - diagonal;\r\n \treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\r\n}\r\n\r\nfloat SDF_Mandlebulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i=0; i<4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n resColor = trap;\r\n\r\n return 0.25*log(m)*sqrt(m)/dz;\r\n}\r\n\r\n//Operators:\r\n\r\nfloat intersection(float d1, float d2)\r\n{\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 )\r\n{\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2)\r\n{\r\n return min(d1,d2);\r\n}\r\n\r\n// Returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform(vec3 point, mat4 trans)\r\n{\r\n\t// Columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\n// Return the distance of the closest object in the scene\r\nfloat sceneMap( vec3 pos ) {\r\n\treturn SDF_Sphere( pos, 1.0 );\r\n}\r\n\r\nfloat mod(int num1, int num2)\r\n{\r\n\tint div = num1/num2;\r\n\treturn float(num1 - div*num2);\r\n}\r\n\r\nint sceneNum()\r\n{\r\n\tfloat x = u_time;\r\n\tfloat cycle = 124.0;\r\n\tfloat fps = 6.0;\r\n\tfloat t = mod(x, cycle);\r\n\tif(t <= 42.0) { return 2; }\r\n\telse if(t <= 80.0) { return 1; }\r\n\telse { return 3; }\r\n}\r\n\r\nfloat sceneMap2( vec3 pos ){\r\n\r\n\tfloat t = u_time/4.0;\r\n\tint sceneNumber = sceneNum();\r\n\r\n\tfloat angle = 2.0*t/(2.0*3.1415);\r\n\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\r\n\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\r\n\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\r\n\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\r\n\r\n\tmat4 northMat = mat4(1.0); \r\n\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\r\n\tmat4 southMat = mat4(1.0); \r\n\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\r\n\tmat4 westMat = mat4(1.0); \r\n\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\r\n\tmat4 eastMat = mat4(1.0); \r\n\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\r\n\r\n\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\r\n\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\r\n\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\r\n\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\r\n\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\r\n\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\r\n\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\r\n\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\r\n\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\r\n\r\n\tif(sceneNumber == 1)\r\n\t{\r\n\t\t//SCENE 01------------------------------------------------------------\r\n\t\tfloat dist1;\r\n\t\t//vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat);\r\n\t\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), cwMat), northMat);\t\r\n\t\tfloat bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1));\r\n\t\tif(bb1 < .015)\r\n\t\t{\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist1 = SDF_Mandlebulb(newPos1, power);\r\n\t\t}\t\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist1 = bb1;\r\n\t\t}\r\n\r\n\t\tfloat dist2;\r\n\t\t//vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat);\r\n\t\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), ccwMat), eastMat);\t\r\n\t\tfloat bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1));\r\n\t\tif(bb2 < .015)\r\n\t\t{\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist2 = SDF_Mandlebulb(newPos2, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist2 = bb2;\r\n\t\t}\r\n\r\n\t\tfloat dist3;\r\n\t\t// vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat);\r\n\t\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat);\t\r\n\t\tfloat bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb3 < .015)\r\n\t\t{\r\n\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist3 = SDF_Mandlebulb(newPos3, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist3 = bb3;\r\n\t\t}\r\n\r\n\t\treturn un(dist1, un(dist2, dist3));\r\n\t}\r\n\telse if(sceneNumber == 2)\r\n\t{\r\n\t\t//SCENE 02------------------------------------------------------------\r\n\t\tfloat dist4;\r\n\t\tmat4 rotateX = mat4(1.0); rotateX[1][1] = 0.0; rotateX[1][2] = 1.0; rotateX[2][1] = -1.0; rotateX[2][2] = 0.0; //rotate 90 degress about x-axis\r\n\t\tfloat angY = 45.0*3.1415/180.0;\r\n\t\tmat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis\r\n\t\tfloat angZ = (2.0*u_time)*3.1415/180.0;\r\n\t\tmat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis\r\n\t\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \r\n\t\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX);\t\r\n\t\tfloat bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb4 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist4 = SDF_Mandlebulb(newPos4, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist4 = bb4;\r\n\t\t}\r\n\r\n\t\treturn dist4;\r\n\t}\r\n\telse \r\n\t{\r\n\t\t//SCENE 03------------------------------------------------------------\r\n\t\tfloat dist5;\r\n\t\tmat4 rotateX2 = mat4(1.0); rotateX2[1][1] = 0.0; rotateX2[1][2] = 1.0; rotateX2[2][1] = -1.0; rotateX2[2][2] = 0.0; //rotate 90 degress about x-axis\r\n\t\tfloat angY2 = -45.0*3.1415/180.0;\r\n\t\tmat4 rotateY2 = mat4(1.0); rotateY2[0][0] = cos(angY2); rotateY2[0][2] = -sin(angY2); rotateY2[2][0] = sin(angY2); rotateY2[2][2] = cos(angY2); //rotate 45 degrees about y-axis\r\n\t\tfloat angZ2 = (2.0*u_time)*3.1415/180.0;\r\n\t\tmat4 rotateZ2 = mat4(1.0); rotateZ2[0][0] = cos(angZ2); rotateZ2[0][2] = -sin(angZ2); rotateZ2[2][0] = sin(angZ2); rotateZ2[2][2] = cos(angZ2); //spin about y-axis\r\n\t\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), rotateY2), rotateX2), rotateZ2);\t\r\n\t\tfloat bb5 = SDF_Sphere(newPos5, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb5 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist5 = SDF_Mandlebulb(newPos5, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist5 = bb5;\r\n\t\t}\r\n\r\n\t\treturn dist5;\r\n\t}\r\n\t\r\n\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\r\n\t//return dist3;\r\n\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\nvec3 computeNormal( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\r\n\t\t\t\t\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\r\n\t\t\t\t\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\r\n\treturn normal;\r\n}\r\n\r\n// Check for intersection with the scene for increasing t-values\r\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\r\n\tfloat dist;\r\n\tfloat t = 0.01;\r\n\tfor(int i = 0; i < 500; i++) {\r\n\t\tfloat dist = sceneMap2(origin + t * direction);\r\n\t\tif(dist < 0.0001) {\r\n\t\t\treturn vec2(t, 1.0); // intersection\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn vec2(0.0, -1.0); // no intersection\r\n}\r\n\r\n\r\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\r\n\tfloat dot = dot(normalize(toCam + toLight), normal);\r\n\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\r\n}\r\n\r\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\r\nfloat ComputeAO( vec3 pos, vec3 normal ) {\r\n\tfloat tStep = 0.0025;\r\n\tfloat t = 0.0;\r\n\tfloat ao = 1.0;\r\n\tfloat diff = 0.0;\r\n\tfloat k = 72.0;\r\n\tfor(int i = 0; i < 5; i++) {\r\n\t\tvec3 sample = pos + t * normal;\r\n\t\tfloat dist = sceneMap2( sample );\r\n\t\tdiff += pow(0.5, float (i)) * (t - dist);\r\n\t\tt += tStep;\r\n\t}\r\n\tao -= clamp(k * diff, 0.0, 1.0);\r\n\treturn ao;\r\n}\r\n\r\n\r\nvec3 backgroundColor()\r\n{\r\n\tint sn = sceneNum();\r\n\tfloat darken; \r\n\tif(sn == 1)\r\n\t{\r\n\t\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\r\n\t\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\r\n\t}\r\n\telse if(sn == 2)\r\n\t{\r\n\t\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\r\n\t\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\r\n\t}\r\n\t\r\n\tdarken = clamp(darken, 0.2, 1.0);\r\n\r\n\tvec3 a = vec3(0.5, 0.5, 0.5);\r\n\tvec3 b = vec3(0.5, 0.5, 0.5);\r\n\tvec3 c = vec3(2.0, 1.0, 1.0);\r\n\tvec3 d = vec3(0.5, 0.2, 0.25);\r\n\tfloat t = abs(sin(u_time/12.0));\r\n\tvec3 color = a + b*cos(6.28*(c*t + d));\r\n\r\n\treturn darken*color;\r\n}\r\n\r\n\r\nvoid main() {\r\n\t\r\n\t/** Raycasting **/\r\n\t\r\n\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\r\n\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\r\n\t\t\t\t\t\t\t\tgl_FragCoord.y / u_resolution.y) - 1.0;\r\n\r\n\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\r\n\t//vec3 cameraPos = vec3(1, -4, 2);\r\n\t//vec3 cameraPos = vec3(1, 0, 1);\r\n\t\r\n\t// Circle the origin (0, 0, 0)\r\n\t// cameraPos.x = sin(u_time) * 10.0;\r\n\t// cameraPos.z = cos(u_time) * 10.0;\r\n\t\r\n\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\r\n\t\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos);\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\r\n\t\r\n\t// Perform the raymarch\r\n\tvec3 direction = normalize(point_World - cameraPos);\r\n\tvec2 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\t/** Shading and lighting **/\r\n\t\r\n\tif(isect.y > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormal( isectPos );\r\n\t\t\r\n\t\t// Lighting\r\n\t\tvec3 baseMaterial = vec3(0.1, 0.2, 0.2);\r\n\t\tvec3 trapColor;\r\n\t\tint sn = sceneNum();\r\n\t\tif(sn == 1)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(\r\n\t\t\t\tresColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.8), \r\n\t\t\t\tresColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), \r\n\t\t\t\tresColor.z+(cos((u_time)/2.0-isectPos.x)*0.2));\r\n\t\t}\r\n\t\telse if(sn == 2)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(resColor) + vec3(0.4);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\ttrapColor = vec3(0.0, resColor.y+0.4, resColor.z+0.4);\r\n\t\t}\r\n\t\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\r\n\t\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\r\n\t\t\r\n\t\tvec3 toSun = normalize(sunPos - isectPos);\r\n\t\t\r\n\t\tnormal = -normal;\r\n\t\t\r\n\t\t// Visibility test\r\n\t\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\r\n\t\t// float vis = 1.0;\r\n\t\t\r\n\t\t// if(shadowTest.y > 0.0) { // something is blocking this point\r\n\t\t// \tvis = 0.0;\r\n\t\t// }\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t// Phong-ish shading for now\r\n\t\tfloat spec = SpecHighlight( -look, toSun, normal);\r\n\t\t\r\n\t\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\r\n\t\tfloat ao = ComputeAO(isectPos, normal);\r\n\t\t\r\n\t\t// Apply lambertian shading - for now\r\n\t\t\r\n\t\t//gl_FragColor = ao*vec4(baseMaterial, 1.0);\r\n\t\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\r\n\t\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\r\n\t} else {\r\n\t\t// Background color\r\n\t\tgl_FragColor = vec4(backgroundColor(), 1);\r\n\t}\r\n}\r\n" /***/ }), /* 16 */ diff --git a/build/bundle.js.map b/build/bundle.js.map index c4da971e..09cfdd24 100644 --- a/build/bundle.js.map +++ b/build/bundle.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap f67c532b5f68b14de2b1","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/rayMarch-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","aspect","updateProjectionMatrix","gui","GUI","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","buffer","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","composer","shaderPass","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","vertexShader","fragmentShader","renderToScreen","addPass","getElapsedTime"],"mappings":"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AEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa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A;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,QAAO;;AAEP,MAAK;AACL;AACA;;AAEA;;;AAGA,0BAAyB,oCAAoC;AAC7D;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;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CA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,YAAW;;AAEX,+DAA8D,uCAAuC;;AAErG;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA0B;AAC1B;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,yGAAwG;AACxG,MAAK;AACL;;AAEA;AACA;AACA,8JAA6J;AAC7J,2JAA0J;AAC1J,sJAAqJ;AACrJ,uJAAsJ;AACtJ,mJAAkJ;AAClJ;;;AAGA;;AAEA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA,mB;;;;;;AC3kHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;;AAED;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;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E5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA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;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;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;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AAC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EpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA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AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,OAAO;;AAE1B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;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AAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;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EA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,8CAA6C,OAAO;;AAEpD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KA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CA;;AAEA;AACA;;AAEA,uBAAsB;AACtB,uBAAsB;;AAEtB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;AACA;;AAEA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+DAA8D;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AAC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AEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB;AACpB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,8BAA8B;;AAEjD;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;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EA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,oEAAmE;;AAEnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AA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EA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gBAAe,sBAAsB;;AAErC;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,qBAAqB;;AAEnC,gB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EA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;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CA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap f67c532b5f68b14de2b1","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"

      \\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
      \\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
      The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
      \\n \\n
      \\n\\n
      \",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nimport {PROXY_BUFFER_SIZE} from './proxy_geometry'\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n var composer = new EffectComposer(renderer);\r\n var shaderPass = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/rayMarch-frag.glsl')\r\n \r\n });\r\n shaderPass.renderToScreen = true;\r\n composer.addPass(shaderPass);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n composer.render();\r\n // console.log(composer);\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\n#define MAX_GEOMETRY_COUNT 100\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 8.0\\r\\n\\r\\n/* This is how I'm packing the data\\r\\nstruct geometry_t {\\r\\n vec3 position;\\r\\n float type;\\r\\n};\\r\\n*/\\r\\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\\r\\n// uniform int u_count;\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\nvec4 resColor;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t *****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\n//diagonal is the vector from the center of the box to the first quadrant corner\\r\\nfloat boxSDF(vec3 point, vec3 diagonal) {\\r\\n\\tvec3 d = abs(point) - diagonal;\\r\\n \\treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\\r\\n}\\r\\n\\r\\nfloat SDF_Mandlebulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i=0; i<4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n resColor = trap;\\r\\n\\r\\n return 0.25*log(m)*sqrt(m)/dz;\\r\\n}\\r\\n\\r\\n//Operators:\\r\\n\\r\\nfloat intersection(float d1, float d2)\\r\\n{\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 )\\r\\n{\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2)\\r\\n{\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n// Returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform(vec3 point, mat4 trans)\\r\\n{\\r\\n\\t// Columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\n// Return the distance of the closest object in the scene\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\treturn SDF_Sphere( pos, 1.0 );\\r\\n}\\r\\n\\r\\nfloat mod(int num1, int num2)\\r\\n{\\r\\n\\tint div = num1/num2;\\r\\n\\treturn float(num1 - div*num2);\\r\\n}\\r\\n\\r\\nint sceneNum()\\r\\n{\\r\\n\\tfloat x = u_time;\\r\\n\\tfloat cycle = 90.0;// * 20.0;\\r\\n\\tfloat t = (mod(x, cycle)/cycle) * 3.0;\\r\\n\\tif(t <= 1.0) { return 2; }\\r\\n\\telse if(t <= 2.0) { return 1; }\\r\\n\\telse { return 3; }\\r\\n}\\r\\n\\r\\nfloat sceneMap2( vec3 pos ){\\r\\n\\r\\n\\tfloat t = u_time/4.0;\\r\\n\\tint sceneNumber = sceneNum();\\r\\n\\r\\n\\tfloat angle = 2.0*t/(2.0*3.1415);\\r\\n\\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\\r\\n\\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\\r\\n\\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\\r\\n\\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\\r\\n\\r\\n\\tmat4 northMat = mat4(1.0); \\r\\n\\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 southMat = mat4(1.0); \\r\\n\\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 westMat = mat4(1.0); \\r\\n\\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\\r\\n\\tmat4 eastMat = mat4(1.0); \\r\\n\\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\\r\\n\\r\\n\\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\\r\\n\\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\\r\\n\\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\\r\\n\\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\\r\\n\\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\\r\\n\\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\\r\\n\\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\\r\\n\\r\\n\\tif(sceneNumber == 1)\\r\\n\\t{\\r\\n\\t\\t//SCENE 01------------------------------------------------------------\\r\\n\\t\\tfloat dist1;\\r\\n\\t\\t//vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat);\\r\\n\\t\\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), cwMat), northMat);\\t\\r\\n\\t\\tfloat bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb1 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist1 = SDF_Mandlebulb(newPos1, power);\\r\\n\\t\\t}\\t\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist1 = bb1;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist2;\\r\\n\\t\\t//vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat);\\r\\n\\t\\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), ccwMat), eastMat);\\t\\r\\n\\t\\tfloat bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb2 < .015)\\r\\n\\t\\t{\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist2 = SDF_Mandlebulb(newPos2, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist2 = bb2;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist3;\\r\\n\\t\\t// vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat);\\r\\n\\t\\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -0.5*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat);\\t\\r\\n\\t\\tfloat bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb3 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist3 = SDF_Mandlebulb(newPos3, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist3 = bb3;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn un(dist1, un(dist2, dist3));\\r\\n\\t}\\r\\n\\telse if(sceneNumber == 2)\\r\\n\\t{\\r\\n\\t\\t//SCENE 02------------------------------------------------------------\\r\\n\\t\\tfloat dist4;\\r\\n\\t\\tmat4 rotateX = mat4(1.0); rotateX[1][1] = 0.0; rotateX[1][2] = 1.0; rotateX[2][1] = -1.0; rotateX[2][2] = 0.0; //rotate 90 degress about x-axis\\r\\n\\t\\tfloat angY = 45.0*3.1415/180.0;\\r\\n\\t\\tmat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis\\r\\n\\t\\tfloat angZ = (2.0*u_time)*3.1415/180.0;\\r\\n\\t\\tmat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis\\r\\n\\t\\tfloat displace = mod(u_time, 90.0)/30.0*3.0; \\r\\n\\t\\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX);\\t\\r\\n\\t\\tfloat bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb4 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist4 = SDF_Mandlebulb(newPos4, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist4 = bb4;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist4;\\r\\n\\t}\\r\\n\\telse \\r\\n\\t{\\r\\n\\t\\t//SCENE 03------------------------------------------------------------\\r\\n\\t\\tfloat dist5;\\r\\n\\t\\tmat4 rotateX2 = mat4(1.0); rotateX2[1][1] = 0.0; rotateX2[1][2] = 1.0; rotateX2[2][1] = -1.0; rotateX2[2][2] = 0.0; //rotate 90 degress about x-axis\\r\\n\\t\\tfloat angY2 = -45.0*3.1415/180.0;\\r\\n\\t\\tmat4 rotateY2 = mat4(1.0); rotateY2[0][0] = cos(angY2); rotateY2[0][2] = -sin(angY2); rotateY2[2][0] = sin(angY2); rotateY2[2][2] = cos(angY2); //rotate 45 degrees about y-axis\\r\\n\\t\\tfloat angZ2 = (2.0*u_time)*3.1415/180.0;\\r\\n\\t\\tmat4 rotateZ2 = mat4(1.0); rotateZ2[0][0] = cos(angZ2); rotateZ2[0][2] = -sin(angZ2); rotateZ2[2][0] = sin(angZ2); rotateZ2[2][2] = cos(angZ2); //spin about y-axis\\r\\n\\t\\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), rotateY2), rotateX2), rotateZ2);\\t\\r\\n\\t\\tfloat bb5 = SDF_Sphere(newPos5, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb5 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist5 = SDF_Mandlebulb(newPos5, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist5 = bb5;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist5;\\r\\n\\t}\\r\\n\\t\\r\\n\\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\\r\\n\\t//return dist3;\\r\\n\\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\nvec3 computeNormal( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Check for intersection with the scene for increasing t-values\\r\\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\tfloat dist;\\r\\n\\tfloat t = 0.01;\\r\\n\\tfor(int i = 0; i < 500; i++) {\\r\\n\\t\\tfloat dist = sceneMap2(origin + t * direction);\\r\\n\\t\\tif(dist < 0.0001) {\\r\\n\\t\\t\\treturn vec2(t, 1.0); // intersection\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn vec2(0.0, -1.0); // no intersection\\r\\n}\\r\\n\\r\\n\\r\\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\\r\\n\\tfloat dot = dot(normalize(toCam + toLight), normal);\\r\\n\\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\\r\\n}\\r\\n\\r\\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\\r\\nfloat ComputeAO( vec3 pos, vec3 normal ) {\\r\\n\\tfloat tStep = 0.0025;\\r\\n\\tfloat t = 0.0;\\r\\n\\tfloat ao = 1.0;\\r\\n\\tfloat diff = 0.0;\\r\\n\\tfloat k = 72.0;\\r\\n\\tfor(int i = 0; i < 5; i++) {\\r\\n\\t\\tvec3 sample = pos + t * normal;\\r\\n\\t\\tfloat dist = sceneMap2( sample );\\r\\n\\t\\tdiff += pow(0.5, float (i)) * (t - dist);\\r\\n\\t\\tt += tStep;\\r\\n\\t}\\r\\n\\tao -= clamp(k * diff, 0.0, 1.0);\\r\\n\\treturn ao;\\r\\n}\\r\\n\\r\\n\\r\\nvec3 backgroundColor()\\r\\n{\\r\\n\\tint sn = sceneNum();\\r\\n\\tfloat darken; \\r\\n\\tif(sn == 1)\\r\\n\\t{\\r\\n\\t\\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\\r\\n\\t\\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\\r\\n\\t}\\r\\n\\telse if(sn == 2)\\r\\n\\t{\\r\\n\\t\\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\\r\\n\\t\\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\\r\\n\\t}\\r\\n\\t\\r\\n\\tdarken = clamp(darken, 0.2, 1.0);\\r\\n\\r\\n\\tvec3 a = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 b = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 c = vec3(2.0, 1.0, 1.0);\\r\\n\\tvec3 d = vec3(0.5, 0.2, 0.25);\\r\\n\\tfloat t = abs(sin(u_time/12.0));\\r\\n\\tvec3 color = a + b*cos(6.28*(c*t + d));\\r\\n\\r\\n\\treturn darken*color;\\r\\n}\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n\\t\\r\\n\\t/** Raycasting **/\\r\\n\\t\\r\\n\\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\\r\\n\\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t\\t\\t\\tgl_FragCoord.y / u_resolution.y) - 1.0;\\r\\n\\r\\n\\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\\r\\n\\t//vec3 cameraPos = vec3(1, -4, 2);\\r\\n\\t//vec3 cameraPos = vec3(1, 0, 1);\\r\\n\\t\\r\\n\\t// Circle the origin (0, 0, 0)\\r\\n\\t// cameraPos.x = sin(u_time) * 10.0;\\r\\n\\t// cameraPos.z = cos(u_time) * 10.0;\\r\\n\\t\\r\\n\\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\\r\\n\\t\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos);\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\\r\\n\\t\\r\\n\\t// Perform the raymarch\\r\\n\\tvec3 direction = normalize(point_World - cameraPos);\\r\\n\\tvec2 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\t/** Shading and lighting **/\\r\\n\\t\\r\\n\\tif(isect.y > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormal( isectPos );\\r\\n\\t\\t\\r\\n\\t\\t// Lighting\\r\\n\\t\\tvec3 baseMaterial = vec3(0.1, 0.2, 0.2);\\r\\n\\t\\tvec3 trapColor;\\r\\n\\t\\tint sn = sceneNum();\\r\\n\\t\\tif(sn == 1)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(\\r\\n\\t\\t\\t\\tresColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.8), \\r\\n\\t\\t\\t\\tresColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), \\r\\n\\t\\t\\t\\tresColor.z+(cos((u_time)/2.0-isectPos.x)*0.2));\\r\\n\\t\\t}\\r\\n\\t\\telse if(sn == 2)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(resColor) + vec3(0.4);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(0.0, resColor.y+0.4, resColor.z+0.4);\\r\\n\\t\\t}\\r\\n\\t\\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\\r\\n\\t\\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\\r\\n\\t\\t\\r\\n\\t\\tvec3 toSun = normalize(sunPos - isectPos);\\r\\n\\t\\t\\r\\n\\t\\tnormal = -normal;\\r\\n\\t\\t\\r\\n\\t\\t// Visibility test\\r\\n\\t\\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\\r\\n\\t\\t// float vis = 1.0;\\r\\n\\t\\t\\r\\n\\t\\t// if(shadowTest.y > 0.0) { // something is blocking this point\\r\\n\\t\\t// \\tvis = 0.0;\\r\\n\\t\\t// }\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t// Phong-ish shading for now\\r\\n\\t\\tfloat spec = SpecHighlight( -look, toSun, normal);\\r\\n\\t\\t\\r\\n\\t\\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\\r\\n\\t\\tfloat ao = ComputeAO(isectPos, normal);\\r\\n\\t\\t\\r\\n\\t\\t// Apply lambertian shading - for now\\r\\n\\t\\t\\r\\n\\t\\t//gl_FragColor = ao*vec4(baseMaterial, 1.0);\\r\\n\\t\\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\\r\\n\\t\\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\\r\\n\\t} else {\\r\\n\\t\\t// Background color\\r\\n\\t\\tgl_FragColor = vec4(backgroundColor(), 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/rayMarch-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 17\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap 7b6f060d86f4e785c168","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/rayMarch-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","listener","AudioListener","sound","PositionalAudio","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","audioLoader","AudioLoader","load","buffer","setBuffer","setLoop","setVolume","play","aspect","updateProjectionMatrix","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","composer","shaderPass","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","vertexShader","fragmentShader","renderToScreen","addPass","getElapsedTime"],"mappings":"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AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,SAAQ,OAAO;AACf;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA,qEAAoE,iCAAiC;;AAErG;;AAEA;AACA;;;;AAIA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA,WAAU,iDAAiD,gBAAgB,uBAAuB,2BAA2B,qBAAqB,qBAAqB,GAAG,gBAAgB,yBAAyB,2BAA2B,gBAAgB,wBAAwB,yBAAyB,+BAA+B,GAAG,sBAAsB,0BAA0B,uBAAuB,2BAA2B,4BAA4B,gBAAgB,iBAAiB,uBAAuB,qBAAqB,kBAAkB,iBAAiB,GAAG;;;AAGlkB;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;;AAEA;AACA;AACA,4C;AACA,YAAW;AACX;AACA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AA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AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA,sBAAqB,mGAAmG,aAAa,2CAA2C,mBAAmB,SAAS,KAAK,4BAA4B,YAAY,gBAAgB,oCAAoC,WAAW,qCAAqC,gBAAgB,uBAAuB,iBAAiB,oCAAoC,eAAe,4BAA4B,uCAAuC,cAAc,iBAAiB;AAC1iB,mBAAkB,iBAAiB,oCAAoC,gBAAgB,mCAAmC,WAAW,YAAY,uBAAuB,qBAAqB,qBAAqB,EAAE,qCAAqC,2BAA2B,YAAY,WAAW,uBAAuB,iBAAiB,oCAAoC,UAAU,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EA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,sBAAsB;;AAE5D;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4BAA2B;;;AAG3B;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC;;AAEvC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,kBAAiB;;AAEjB;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAgB;;AAEhB;;AAEA;;AAEA;AACA;AACA,uDAAsD;;AAEtD;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG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AiH,sDAAsD,oLAAoL,yJAAyJ,GAAG;;AAEjjB,oJAAmJ,sDAAsD,mMAAmM,6PAA6P,4TAA4T,WAAW;;AAEh9B,0CAAyC,wBAAwB,+QAA+Q,4EAA4E,iDAAiD,0KAA0K,yDAAyD,6IAA6I;;AAE7zB,wCAAuC,sBAAsB,0MAA0M,wKAAwK,mCAAmC,yKAAyK;;AAE3nB,2CAA0C,yKAAyK,8EAA8E,GAAG;;AAEpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iCAAgC;;AAEhC;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,0DAAyD;AACzD,0CAAyC;AACzC,0CAAyC;;AAEzC;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,eAAc,YAAY;;AAE1B;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,uBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB;;AAEhB;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,cAAa,+BAA+B;AAC5C,cAAa,aAAa;;AAE1B,UAAS,cAAc;AACvB,mBAAkB,mCAAmC;;AAErD,kBAAiB,cAAc;AAC/B,eAAc,cAAc;;AAE5B,aAAY,cAAc;AAC1B,iBAAgB,aAAa;AAC7B,mBAAkB,aAAa;AAC/B,sBAAqB;;AAErB,IAAG;;AAEH;;AAEA,YAAW,cAAc;AACzB,qBAAoB;;AAEpB,IAAG;;AAEH;;AAEA,eAAc,cAAc;AAC5B,wBAAuB;;AAEvB,IAAG;;AAEH;;AAEA,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,cAAa,cAAc;AAC3B,gBAAe;;AAEf,IAAG;;AAEH;;AAEA,gBAAe,cAAc;AAC7B,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,sBAAqB,cAAc;AACnC,wBAAuB,WAAW;AAClC,uBAAsB;;AAEtB,IAAG;;AAEH;;AAEA,mBAAkB;;AAElB,IAAG;;AAEH;;AAEA,mBAAkB;;AAElB,IAAG;;AAEH;;AAEA,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,iBAAgB,iBAAiB;AACjC,cAAa,WAAW;AACxB,aAAY,cAAc;AAC1B,eAAc;;AAEd,IAAG;;AAEH;;AAEA,wBAAuB,YAAY;;AAEnC,wBAAuB;AACvB,kBAAiB;AACjB,cAAa;;AAEb,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,2BAA0B,YAAY;AACtC,8BAA6B,YAAY;;AAEzC,iBAAgB;AAChB,cAAa;AACb,iBAAgB;AAChB,kBAAiB;AACjB,iBAAgB;AAChB,gBAAe;AACf,oBAAmB;AACnB,cAAa;;AAEb,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,oBAAmB,YAAY;AAC/B,uBAAsB,YAAY;;AAElC,kBAAiB;AACjB,cAAa;AACb,iBAAgB;AAChB,cAAa;AACb,iBAAgB;;AAEhB,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,qBAAoB,YAAY;AAChC,wBAAuB,YAAY;;AAEnC,uBAAsB;AACtB,kBAAiB;AACjB,iBAAgB;AAChB;AACA,KAAI,EAAE;;AAEN;AACA,qBAAoB;AACpB,cAAa;AACb,iBAAgB;AAChB,cAAa;AACb;AACA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA,cAAa,+BAA+B;AAC5C,cAAa,aAAa;AAC1B,WAAU,aAAa;AACvB,YAAW,aAAa;AACxB,UAAS,cAAc;AACvB,mBAAkB;;AAElB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB;AAChB;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB,+BAA+B;AAC/C,iBAAgB,+BAA+B;AAC/C,kBAAiB;AACjB;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB,+BAA+B;AAC/C,kBAAiB,aAAa;AAC9B,kBAAiB,WAAW;AAC5B,wBAAuB,WAAW;AAClC;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,iBAAgB,WAAW;AAC3B,kBAAiB;AACjB;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA,aAAY,cAAc;AAC1B,aAAY,aAAa;AACzB,eAAc;AACd,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA,iBAAgB,cAAc;AAC9B,aAAY;AACZ,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA,gBAAe;AACf,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,iBAAgB,WAAW;AAC3B,0BAAyB;AACzB;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mCAAkC;;AAElC,mCAAkC;AAClC,0BAAyB;AACzB,8BAA6B;;AAE7B,sCAAqC;;AAErC,+BAA8B;AAC9B,yBAAwB;;AAExB,wBAAuB;AACvB,iCAAgC;;AAEhC,oBAAmB;;AAEnB,iBAAgB;;AAEhB,4BAA2B;;AAE3B,gCAA+B;;AAE/B,uEAAsE;AACtE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;;AAElE,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;;AAEhD,6EAA4E;AAC5E,6EAA4E;;AAE5E,SAAQ;;AAER,4FAA2F;;AAE3F,QAAO;;AAEP;;AAEA;;AAEA,mCAAkC;;AAElC,6BAA4B;AAC5B,6BAA4B;AAC5B,0BAAyB;;AAEzB,wBAAuB;AACvB,iCAAgC;;AAEhC,oBAAmB;;AAEnB;;AAEA,gCAA+B;;AAE/B,mDAAkD;;AAElD;;AAEA,SAAQ,8BAA8B;;AAEtC,8CAA6C;;AAE7C;;AAEA,SAAQ,OAAO;;AAEf,8CAA6C;AAC7C,4CAA2C;AAC3C,gCAA+B;AAC/B,mCAAkC;;AAElC,SAAQ;;AAER,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,uCAAsC,OAAO;;AAE7C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;AACA;;AAEA,oDAAmD,QAAQ;;AAE3D;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;;AAGA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sDAAqD;;AAErD,mCAAkC;AAClC,oCAAmC;AACnC,6BAA4B;AAC5B,yBAAwB;AACxB,4BAA2B;AAC3B,2BAA0B;;AAE1B,8BAA6B;AAC7B,wBAAuB;;AAEvB,uBAAsB;;AAEtB,mBAAkB;;AAElB,qCAAoC;;AAEpC,+CAA8C;;AAE9C,4BAA2B;AAC3B,qGAAoG;AACpG,qGAAoG;;AAEpG,0BAAyB;;AAEzB,oEAAmE;AACnE,2CAA0C;AAC1C,wDAAuD;;AAEvD,mCAAkC;;AAElC,OAAM;;AAEN;;AAEA;;AAEA,sDAAqD;;AAErD,yBAAwB;AACxB,4BAA2B;AAC3B,4BAA2B;;AAE3B,0BAAyB;AACzB,4BAA2B;AAC3B,+BAA8B;AAC9B,4BAA2B;AAC3B,2BAA0B;AAC1B,8BAA6B;;AAE7B,uBAAsB;;AAEtB,mBAAkB;;AAElB,4CAA2C;;AAE3C,4CAA2C;;AAE3C,uEAAsE;;AAEtE,2BAA0B;;AAE1B,sDAAqD;AACrD,8BAA6B;;AAE7B,6BAA4B;;AAE5B,0DAAyD;;AAEzD,SAAQ,OAAO;;AAEf,qCAAoC;AACpC,8EAA6E;AAC7E,wDAAuD;;AAEvD,SAAQ;;AAER,wFAAuF;;AAEvF,QAAO;;AAEP,OAAM;;AAEN;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,uBAAuB;;AAE7D;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gCAA+B;AAC/B,gCAA+B;;AAE/B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,yBAAwB;;AAExB;AACA;AACA;;AAEA;AACA;;AAEA,qBAAoB;;AAEpB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA,kBAAiB;AACjB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,2CAA0C;;AAE1C;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,qBAAoB,SAAS;AAC7B;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,iBAAiB;;AAEzC,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,iBAAgB,gBAAgB,aAAa,iBAAiB,YAAY,EAAE;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,qCAAoC,6EAA6E,GAAG;AACpH,uCAAsC,8CAA8C,GAAG;;AAEvF;;AAEA;AACA;;AAEA,oBAAmB;AACnB,uBAAsB;AACtB,yBAAwB;;AAExB,yBAAwB;AACxB,6BAA4B;AAC5B,6BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sCAAqC,OAAO;;AAE5C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,yCAAwC,OAAO;;AAE/C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;;AAEjF;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,+CAA8C;;AAE9C;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kBAAiB,eAAe;AAChC,kBAAiB,eAAe;AAChC,kBAAiB,eAAe;;AAEhC;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;;AAE9B;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,iBAAiB;AACjC,iBAAgB,iBAAiB;AACjC,iBAAgB,iBAAiB;;AAEjC;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;A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AEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;A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AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA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A;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;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;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,sBAAqB,eAAe;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;AAEA,wCAAuC,SAAS;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A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EA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;AACA,gDAA+C;;AAE/C;;AAEA;;AAEA;;AAEA;AACA,8CAA6C;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 7b6f060d86f4e785c168","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\n//Audio and Audio Analysis variables\r\n \r\n//Create an AudioListener and add it to the camera\r\nvar listener = new THREE.AudioListener();\r\n \r\n// create a global audio source\r\nvar sound = new THREE.PositionalAudio( listener );\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n\r\n var audioLoader = new THREE.AudioLoader();\r\n \r\n //Load a sound and set it as the Audio object's buffer\r\n audioLoader.load( 'Dubstep_Sub-Mix_2016.mp3', function( buffer ) {\r\n sound.setBuffer( buffer );\r\n sound.setLoop(true);\r\n sound.setVolume(1.0);\r\n sound.play();\r\n }); \r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n // var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n // gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
      \\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
      \\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
      The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
      \\n \\n
      \\n\\n
      \",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nimport {PROXY_BUFFER_SIZE} from './proxy_geometry'\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n var composer = new EffectComposer(renderer);\r\n var shaderPass = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/rayMarch-frag.glsl')\r\n \r\n });\r\n shaderPass.renderToScreen = true;\r\n composer.addPass(shaderPass);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n composer.render();\r\n // console.log(composer);\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\n#define MAX_GEOMETRY_COUNT 100\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 10.0\\r\\n\\r\\n/* This is how I'm packing the data\\r\\nstruct geometry_t {\\r\\n vec3 position;\\r\\n float type;\\r\\n};\\r\\n*/\\r\\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\\r\\n// uniform int u_count;\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\nvec4 resColor;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t *****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\n//diagonal is the vector from the center of the box to the first quadrant corner\\r\\nfloat boxSDF(vec3 point, vec3 diagonal) {\\r\\n\\tvec3 d = abs(point) - diagonal;\\r\\n \\treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\\r\\n}\\r\\n\\r\\nfloat SDF_Mandlebulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i=0; i<4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n resColor = trap;\\r\\n\\r\\n return 0.25*log(m)*sqrt(m)/dz;\\r\\n}\\r\\n\\r\\n//Operators:\\r\\n\\r\\nfloat intersection(float d1, float d2)\\r\\n{\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 )\\r\\n{\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2)\\r\\n{\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n// Returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform(vec3 point, mat4 trans)\\r\\n{\\r\\n\\t// Columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\n// Return the distance of the closest object in the scene\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\treturn SDF_Sphere( pos, 1.0 );\\r\\n}\\r\\n\\r\\nfloat mod(int num1, int num2)\\r\\n{\\r\\n\\tint div = num1/num2;\\r\\n\\treturn float(num1 - div*num2);\\r\\n}\\r\\n\\r\\nint sceneNum()\\r\\n{\\r\\n\\tfloat x = u_time;\\r\\n\\tfloat cycle = 124.0;\\r\\n\\tfloat fps = 6.0;\\r\\n\\tfloat t = mod(x, cycle);\\r\\n\\tif(t <= 42.0) { return 2; }\\r\\n\\telse if(t <= 80.0) { return 1; }\\r\\n\\telse { return 3; }\\r\\n}\\r\\n\\r\\nfloat sceneMap2( vec3 pos ){\\r\\n\\r\\n\\tfloat t = u_time/4.0;\\r\\n\\tint sceneNumber = sceneNum();\\r\\n\\r\\n\\tfloat angle = 2.0*t/(2.0*3.1415);\\r\\n\\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\\r\\n\\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\\r\\n\\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\\r\\n\\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\\r\\n\\r\\n\\tmat4 northMat = mat4(1.0); \\r\\n\\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 southMat = mat4(1.0); \\r\\n\\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 westMat = mat4(1.0); \\r\\n\\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\\r\\n\\tmat4 eastMat = mat4(1.0); \\r\\n\\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\\r\\n\\r\\n\\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\\r\\n\\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\\r\\n\\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\\r\\n\\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\\r\\n\\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\\r\\n\\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\\r\\n\\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\\r\\n\\r\\n\\tif(sceneNumber == 1)\\r\\n\\t{\\r\\n\\t\\t//SCENE 01------------------------------------------------------------\\r\\n\\t\\tfloat dist1;\\r\\n\\t\\t//vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat);\\r\\n\\t\\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), cwMat), northMat);\\t\\r\\n\\t\\tfloat bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb1 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist1 = SDF_Mandlebulb(newPos1, power);\\r\\n\\t\\t}\\t\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist1 = bb1;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist2;\\r\\n\\t\\t//vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat);\\r\\n\\t\\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), ccwMat), eastMat);\\t\\r\\n\\t\\tfloat bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb2 < .015)\\r\\n\\t\\t{\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist2 = SDF_Mandlebulb(newPos2, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist2 = bb2;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist3;\\r\\n\\t\\t// vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat);\\r\\n\\t\\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat);\\t\\r\\n\\t\\tfloat bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb3 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist3 = SDF_Mandlebulb(newPos3, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist3 = bb3;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn un(dist1, un(dist2, dist3));\\r\\n\\t}\\r\\n\\telse if(sceneNumber == 2)\\r\\n\\t{\\r\\n\\t\\t//SCENE 02------------------------------------------------------------\\r\\n\\t\\tfloat dist4;\\r\\n\\t\\tmat4 rotateX = mat4(1.0); rotateX[1][1] = 0.0; rotateX[1][2] = 1.0; rotateX[2][1] = -1.0; rotateX[2][2] = 0.0; //rotate 90 degress about x-axis\\r\\n\\t\\tfloat angY = 45.0*3.1415/180.0;\\r\\n\\t\\tmat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis\\r\\n\\t\\tfloat angZ = (2.0*u_time)*3.1415/180.0;\\r\\n\\t\\tmat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis\\r\\n\\t\\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \\r\\n\\t\\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX);\\t\\r\\n\\t\\tfloat bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb4 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist4 = SDF_Mandlebulb(newPos4, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist4 = bb4;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist4;\\r\\n\\t}\\r\\n\\telse \\r\\n\\t{\\r\\n\\t\\t//SCENE 03------------------------------------------------------------\\r\\n\\t\\tfloat dist5;\\r\\n\\t\\tmat4 rotateX2 = mat4(1.0); rotateX2[1][1] = 0.0; rotateX2[1][2] = 1.0; rotateX2[2][1] = -1.0; rotateX2[2][2] = 0.0; //rotate 90 degress about x-axis\\r\\n\\t\\tfloat angY2 = -45.0*3.1415/180.0;\\r\\n\\t\\tmat4 rotateY2 = mat4(1.0); rotateY2[0][0] = cos(angY2); rotateY2[0][2] = -sin(angY2); rotateY2[2][0] = sin(angY2); rotateY2[2][2] = cos(angY2); //rotate 45 degrees about y-axis\\r\\n\\t\\tfloat angZ2 = (2.0*u_time)*3.1415/180.0;\\r\\n\\t\\tmat4 rotateZ2 = mat4(1.0); rotateZ2[0][0] = cos(angZ2); rotateZ2[0][2] = -sin(angZ2); rotateZ2[2][0] = sin(angZ2); rotateZ2[2][2] = cos(angZ2); //spin about y-axis\\r\\n\\t\\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), rotateY2), rotateX2), rotateZ2);\\t\\r\\n\\t\\tfloat bb5 = SDF_Sphere(newPos5, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb5 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist5 = SDF_Mandlebulb(newPos5, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist5 = bb5;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist5;\\r\\n\\t}\\r\\n\\t\\r\\n\\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\\r\\n\\t//return dist3;\\r\\n\\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\nvec3 computeNormal( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Check for intersection with the scene for increasing t-values\\r\\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\tfloat dist;\\r\\n\\tfloat t = 0.01;\\r\\n\\tfor(int i = 0; i < 500; i++) {\\r\\n\\t\\tfloat dist = sceneMap2(origin + t * direction);\\r\\n\\t\\tif(dist < 0.0001) {\\r\\n\\t\\t\\treturn vec2(t, 1.0); // intersection\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn vec2(0.0, -1.0); // no intersection\\r\\n}\\r\\n\\r\\n\\r\\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\\r\\n\\tfloat dot = dot(normalize(toCam + toLight), normal);\\r\\n\\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\\r\\n}\\r\\n\\r\\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\\r\\nfloat ComputeAO( vec3 pos, vec3 normal ) {\\r\\n\\tfloat tStep = 0.0025;\\r\\n\\tfloat t = 0.0;\\r\\n\\tfloat ao = 1.0;\\r\\n\\tfloat diff = 0.0;\\r\\n\\tfloat k = 72.0;\\r\\n\\tfor(int i = 0; i < 5; i++) {\\r\\n\\t\\tvec3 sample = pos + t * normal;\\r\\n\\t\\tfloat dist = sceneMap2( sample );\\r\\n\\t\\tdiff += pow(0.5, float (i)) * (t - dist);\\r\\n\\t\\tt += tStep;\\r\\n\\t}\\r\\n\\tao -= clamp(k * diff, 0.0, 1.0);\\r\\n\\treturn ao;\\r\\n}\\r\\n\\r\\n\\r\\nvec3 backgroundColor()\\r\\n{\\r\\n\\tint sn = sceneNum();\\r\\n\\tfloat darken; \\r\\n\\tif(sn == 1)\\r\\n\\t{\\r\\n\\t\\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\\r\\n\\t\\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\\r\\n\\t}\\r\\n\\telse if(sn == 2)\\r\\n\\t{\\r\\n\\t\\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\\r\\n\\t\\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\\r\\n\\t}\\r\\n\\t\\r\\n\\tdarken = clamp(darken, 0.2, 1.0);\\r\\n\\r\\n\\tvec3 a = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 b = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 c = vec3(2.0, 1.0, 1.0);\\r\\n\\tvec3 d = vec3(0.5, 0.2, 0.25);\\r\\n\\tfloat t = abs(sin(u_time/12.0));\\r\\n\\tvec3 color = a + b*cos(6.28*(c*t + d));\\r\\n\\r\\n\\treturn darken*color;\\r\\n}\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n\\t\\r\\n\\t/** Raycasting **/\\r\\n\\t\\r\\n\\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\\r\\n\\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t\\t\\t\\tgl_FragCoord.y / u_resolution.y) - 1.0;\\r\\n\\r\\n\\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\\r\\n\\t//vec3 cameraPos = vec3(1, -4, 2);\\r\\n\\t//vec3 cameraPos = vec3(1, 0, 1);\\r\\n\\t\\r\\n\\t// Circle the origin (0, 0, 0)\\r\\n\\t// cameraPos.x = sin(u_time) * 10.0;\\r\\n\\t// cameraPos.z = cos(u_time) * 10.0;\\r\\n\\t\\r\\n\\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\\r\\n\\t\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos);\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\\r\\n\\t\\r\\n\\t// Perform the raymarch\\r\\n\\tvec3 direction = normalize(point_World - cameraPos);\\r\\n\\tvec2 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\t/** Shading and lighting **/\\r\\n\\t\\r\\n\\tif(isect.y > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormal( isectPos );\\r\\n\\t\\t\\r\\n\\t\\t// Lighting\\r\\n\\t\\tvec3 baseMaterial = vec3(0.1, 0.2, 0.2);\\r\\n\\t\\tvec3 trapColor;\\r\\n\\t\\tint sn = sceneNum();\\r\\n\\t\\tif(sn == 1)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(\\r\\n\\t\\t\\t\\tresColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.8), \\r\\n\\t\\t\\t\\tresColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), \\r\\n\\t\\t\\t\\tresColor.z+(cos((u_time)/2.0-isectPos.x)*0.2));\\r\\n\\t\\t}\\r\\n\\t\\telse if(sn == 2)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(resColor) + vec3(0.4);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(0.0, resColor.y+0.4, resColor.z+0.4);\\r\\n\\t\\t}\\r\\n\\t\\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\\r\\n\\t\\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\\r\\n\\t\\t\\r\\n\\t\\tvec3 toSun = normalize(sunPos - isectPos);\\r\\n\\t\\t\\r\\n\\t\\tnormal = -normal;\\r\\n\\t\\t\\r\\n\\t\\t// Visibility test\\r\\n\\t\\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\\r\\n\\t\\t// float vis = 1.0;\\r\\n\\t\\t\\r\\n\\t\\t// if(shadowTest.y > 0.0) { // something is blocking this point\\r\\n\\t\\t// \\tvis = 0.0;\\r\\n\\t\\t// }\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t// Phong-ish shading for now\\r\\n\\t\\tfloat spec = SpecHighlight( -look, toSun, normal);\\r\\n\\t\\t\\r\\n\\t\\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\\r\\n\\t\\tfloat ao = ComputeAO(isectPos, normal);\\r\\n\\t\\t\\r\\n\\t\\t// Apply lambertian shading - for now\\r\\n\\t\\t\\r\\n\\t\\t//gl_FragColor = ao*vec4(baseMaterial, 1.0);\\r\\n\\t\\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\\r\\n\\t\\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\\r\\n\\t} else {\\r\\n\\t\\t// Background color\\r\\n\\t\\tgl_FragColor = vec4(backgroundColor(), 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/rayMarch-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 17\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file From 862040dc4d4ee22c0549d1d48672d0280ef18d92 Mon Sep 17 00:00:00 2001 From: Joe Klinger Date: Wed, 3 May 2017 00:58:37 -0400 Subject: [PATCH 17/20] Redid our project again in 20 minutes --- matrices.txt | 37 +++++++ new formatted matrices.txt | 18 ++++ src/glsl/secondPass-frag.glsl | 6 +- src/rayMarching.js | 158 +++++++++++++++++++++++++++--- src/rayMarchingCOPY.js | 177 ++++++++++++++++++++++++++++++++++ 5 files changed, 382 insertions(+), 14 deletions(-) create mode 100644 matrices.txt create mode 100644 new formatted matrices.txt create mode 100644 src/rayMarchingCOPY.js diff --git a/matrices.txt b/matrices.txt new file mode 100644 index 00000000..45003cc0 --- /dev/null +++ b/matrices.txt @@ -0,0 +1,37 @@ + var angle = clock.getElapsedTime() / (4.0 * 3.1415); + + var cwMat = new THREE.Matrix4(); + cwMat.makeRotationY(angle); + + var ccwMat = new THREE.Matrix4(); + ccwMat.makeRotationY(-angle); + + var northMat = new THREE.Matrix4(); + northMat.makeRotationX(angle); + + var southMat = new THREE.Matrix4(); + southMat.makeRotationX(-angle); + + var eastMat = new THREE.Matrix4(); + eastMat.makeRotationZ(angle); + + var westMat = new THREE.Matrix4(); + westMat.makeRotationZ(-angle); + + var rotateX1 = new THREE.Matrix4(); + rotateX1.makeRotationX(3.1415 / 2.0); + + var rotateY1 = new THREE.Matrix4(); + rotateY1.makeRotationY(45.0 * 3.1415 / 180.0); + + var rotateZ1 = new THREE.Matrix4(); + rotateZ1.makeRotationZ((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0); + + var rotateX2 = new THREE.Matrix4(); + rotateX2.makeRotationX(3.1415 / 2.0); + + var rotateY2 = new THREE.Matrix4(); + rotateY2.makeRotationY(-45.0 * 3.1415 / 180.0); + + var rotateZ2 = new THREE.Matrix4(); + rotateZ2.makeRotationY((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0); \ No newline at end of file diff --git a/new formatted matrices.txt b/new formatted matrices.txt new file mode 100644 index 00000000..c70e6c36 --- /dev/null +++ b/new formatted matrices.txt @@ -0,0 +1,18 @@ +float angle = 2.0*t/(2.0*3.1415); + +var cwMat = new THREE.Matrix4(); //transform for moving clockwise +cwMat.makeRotationY(angle); //rotating about y-axis, based on utime + +var ccwMat = new THREE.Matrix4(); //transform for moving counterclockwise +ccwMat.makeRotationY(-angle); //rotating about y-axis, based on utime + +var northMat = new THREE.Matrix4(); +northMat.makeRotationX(angle); //rotating about x-axis, based on utime + +var southMat = new THREE.Matrix4(); +southMat.makeRotationX(-angle); //rotating about x-axis, based on utime + +var westMat = new THREE.Matrix4(); +westMat.makeRotationZ(-angle); //rotating about z-axis, based on utime + +var eastMat = new THREE.Matrix4(); \ No newline at end of file diff --git a/src/glsl/secondPass-frag.glsl b/src/glsl/secondPass-frag.glsl index 94bfe287..ce352831 100644 --- a/src/glsl/secondPass-frag.glsl +++ b/src/glsl/secondPass-frag.glsl @@ -11,17 +11,17 @@ varying vec2 f_uv; -uniform sampler2D u_primaryRayPass; +uniform sampler2D u_firstPass; uniform sampler2D u_previousFrame; // The sole purpose of this pass is to compute motion blur between the current and previous frames void main() { #ifdef MOTION_BLUR for(float w = 0.0; w <= 1.0; w += 0.2) { - gl_FragColor += (1.0 - w) * texture2D(u_primaryRayPass, f_uv) + w * texture2D(u_previousFrame, f_uv); + gl_FragColor += (1.0 - w) * texture2D(u_firstPass, f_uv) + w * texture2D(u_previousFrame, f_uv); } gl_FragColor /= 1.0 / 0.2; // divide by the number of samples (1 / stepSize) #else - gl_FragColor = texture2D(u_primaryRayPass, f_uv); + gl_FragColor = texture2D(u_firstPass, f_uv); #endif } diff --git a/src/rayMarching.js b/src/rayMarching.js index e0fcb507..0c9e46a8 100644 --- a/src/rayMarching.js +++ b/src/rayMarching.js @@ -1,11 +1,11 @@ const THREE = require('three'); const EffectComposer = require('three-effectcomposer')(THREE) -import {PROXY_BUFFER_SIZE} from './proxy_geometry' - export default function RayMarcher(renderer, scene, camera) { - var composer = new EffectComposer(renderer); - var shaderPass = new EffectComposer.ShaderPass({ + + var target1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight); + var composer1 = new EffectComposer(renderer, target1); + var shaderPass1 = new EffectComposer.ShaderPass({ uniforms: { u_time: { type: 'f', @@ -22,20 +22,156 @@ export default function RayMarcher(renderer, scene, camera) { u_aspect: { type: 'f', value: camera.aspect + }, + u_cwMat: { + type: 'm4v', + value: null + }, + u_ccwMat: { + type: 'm4v', + value: null + }, + u_northMat: { + type: 'm4v', + value: null + }, + u_southMat: { + type: 'm4v', + value: null + }, + u_westMat: { + type: 'm4v', + value: null + }, + u_eastMat: { + type: 'm4v', + value: null + }, + u_rotateX1: { + type: 'm4v', + value: null + }, + u_rotateY1: { + type: 'm4v', + value: null + }, + u_rotateZ1: { + type: 'm4v', + value: null + }, + u_rotateX2: { + type: 'm4v', + value: null + }, + u_rotateY2: { + type: 'm4v', + value: null + }, + u_rotateZ2: { + type: 'm4v', + value: null + } + }, + vertexShader: require('./glsl/pass-vert.glsl'), + fragmentShader: require('./glsl/firstPass-frag.glsl') + }); + + var composer2 = new EffectComposer(renderer); + var shaderPass2 = new EffectComposer.ShaderPass({ + uniforms: { + u_firstPass: { + type: 't', + value: null + }, + u_previousFrame: { + type: 't', + value: null } }, vertexShader: require('./glsl/pass-vert.glsl'), - fragmentShader: require('./glsl/rayMarch-frag.glsl') - + fragmentShader: require('./glsl/secondPass-frag.glsl') }); - shaderPass.renderToScreen = true; - composer.addPass(shaderPass); + shaderPass2.renderToScreen = true; + shaderPass2.material.uniforms.u_firstPass.value = composer1.writeBuffer.texture; + + var target3 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight); + var composer3 = new EffectComposer(renderer, target3); + var shaderPass3 = new EffectComposer.ShaderPass({ + uniforms: { + u_input: { + type: 't', + value: null + } + }, + vertexShader: require('./glsl/pass-vert.glsl'), + fragmentShader: require('./glsl/thirdPass-frag.glsl') + }); + shaderPass2.material.uniforms.u_previousFrame.value = composer3.writeBuffer.texture; + shaderPass3.material.uniforms.u_input.value = composer1.writeBuffer.texture; + + composer1.addPass(shaderPass1); + composer2.addPass(shaderPass2); + composer3.addPass(shaderPass3); return { render: function(buffer, clock) { - shaderPass.uniforms["u_time"].value = clock.getElapsedTime(); - composer.render(); - // console.log(composer); + shaderPass1.uniforms["u_time"].value = clock.getElapsedTime(); + + // Mandelbulb transformation uniforms + var angle = clock.getElapsedTime() / (4.0 * 3.1415); + + var cwMat = new THREE.Matrix4(); + cwMat.makeRotationY(angle); + + var ccwMat = new THREE.Matrix4(); + ccwMat.makeRotationY(-angle); + + var northMat = new THREE.Matrix4(); + northMat.makeRotationX(angle); + + var southMat = new THREE.Matrix4(); + southMat.makeRotationX(-angle); + + var eastMat = new THREE.Matrix4(); + eastMat.makeRotationZ(angle); + + var westMat = new THREE.Matrix4(); + westMat.makeRotationZ(-angle); + + var rotateX1 = new THREE.Matrix4(); + rotateX1.makeRotationX(3.1415 / 2.0); + + var rotateY1 = new THREE.Matrix4(); + rotateY1.makeRotationY(45.0 * 3.1415 / 180.0); + + var rotateZ1 = new THREE.Matrix4(); + rotateZ1.makeRotationZ((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0); + + var rotateX2 = new THREE.Matrix4(); + rotateX2.makeRotationX(3.1415 / 2.0); + + var rotateY2 = new THREE.Matrix4(); + rotateY2.makeRotationY(-45.0 * 3.1415 / 180.0); + + var rotateZ2 = new THREE.Matrix4(); + rotateZ2.makeRotationY((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0); + + shaderPass1.uniforms["u_cwMat"].value = cwMat; + shaderPass1.uniforms["u_ccwMat"].value = ccwMat; + shaderPass1.uniforms["u_northMat"].value = northMat; + shaderPass1.uniforms["u_southMat"].value = southMat; + shaderPass1.uniforms["u_westMat"].value = westMat; + shaderPass1.uniforms["u_eastMat"].value = eastMat; + shaderPass1.uniforms["u_rotateX1"].value = rotateX1; + shaderPass1.uniforms["u_rotateY1"].value = rotateY1; + shaderPass1.uniforms["u_rotateZ1"].value = rotateZ1; + shaderPass1.uniforms["u_rotateX2"].value = rotateX2; + shaderPass1.uniforms["u_rotateY2"].value = rotateY2; + shaderPass1.uniforms["u_rotateZ2"].value = rotateZ2; + + composer1.render(); + composer2.render(); + composer3.render(); } } } \ No newline at end of file diff --git a/src/rayMarchingCOPY.js b/src/rayMarchingCOPY.js new file mode 100644 index 00000000..0c9e46a8 --- /dev/null +++ b/src/rayMarchingCOPY.js @@ -0,0 +1,177 @@ +const THREE = require('three'); +const EffectComposer = require('three-effectcomposer')(THREE) + +export default function RayMarcher(renderer, scene, camera) { + + var target1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight); + var composer1 = new EffectComposer(renderer, target1); + var shaderPass1 = new EffectComposer.ShaderPass({ + uniforms: { + u_time: { + type: 'f', + value: 0 + }, + u_resolution: { + type: 'v2', + value: new THREE.Vector2(window.innerWidth, window.innerHeight) + }, + u_fovy: { + type: 'f', + value: camera.fov + }, + u_aspect: { + type: 'f', + value: camera.aspect + }, + u_cwMat: { + type: 'm4v', + value: null + }, + u_ccwMat: { + type: 'm4v', + value: null + }, + u_northMat: { + type: 'm4v', + value: null + }, + u_southMat: { + type: 'm4v', + value: null + }, + u_westMat: { + type: 'm4v', + value: null + }, + u_eastMat: { + type: 'm4v', + value: null + }, + u_rotateX1: { + type: 'm4v', + value: null + }, + u_rotateY1: { + type: 'm4v', + value: null + }, + u_rotateZ1: { + type: 'm4v', + value: null + }, + u_rotateX2: { + type: 'm4v', + value: null + }, + u_rotateY2: { + type: 'm4v', + value: null + }, + u_rotateZ2: { + type: 'm4v', + value: null + } + }, + vertexShader: require('./glsl/pass-vert.glsl'), + fragmentShader: require('./glsl/firstPass-frag.glsl') + }); + + var composer2 = new EffectComposer(renderer); + var shaderPass2 = new EffectComposer.ShaderPass({ + uniforms: { + u_firstPass: { + type: 't', + value: null + }, + u_previousFrame: { + type: 't', + value: null + } + }, + vertexShader: require('./glsl/pass-vert.glsl'), + fragmentShader: require('./glsl/secondPass-frag.glsl') + }); + shaderPass2.renderToScreen = true; + shaderPass2.material.uniforms.u_firstPass.value = composer1.writeBuffer.texture; + + var target3 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight); + var composer3 = new EffectComposer(renderer, target3); + var shaderPass3 = new EffectComposer.ShaderPass({ + uniforms: { + u_input: { + type: 't', + value: null + } + }, + vertexShader: require('./glsl/pass-vert.glsl'), + fragmentShader: require('./glsl/thirdPass-frag.glsl') + }); + shaderPass2.material.uniforms.u_previousFrame.value = composer3.writeBuffer.texture; + shaderPass3.material.uniforms.u_input.value = composer1.writeBuffer.texture; + + composer1.addPass(shaderPass1); + composer2.addPass(shaderPass2); + composer3.addPass(shaderPass3); + + return { + render: function(buffer, clock) { + shaderPass1.uniforms["u_time"].value = clock.getElapsedTime(); + + // Mandelbulb transformation uniforms + var angle = clock.getElapsedTime() / (4.0 * 3.1415); + + var cwMat = new THREE.Matrix4(); + cwMat.makeRotationY(angle); + + var ccwMat = new THREE.Matrix4(); + ccwMat.makeRotationY(-angle); + + var northMat = new THREE.Matrix4(); + northMat.makeRotationX(angle); + + var southMat = new THREE.Matrix4(); + southMat.makeRotationX(-angle); + + var eastMat = new THREE.Matrix4(); + eastMat.makeRotationZ(angle); + + var westMat = new THREE.Matrix4(); + westMat.makeRotationZ(-angle); + + var rotateX1 = new THREE.Matrix4(); + rotateX1.makeRotationX(3.1415 / 2.0); + + var rotateY1 = new THREE.Matrix4(); + rotateY1.makeRotationY(45.0 * 3.1415 / 180.0); + + var rotateZ1 = new THREE.Matrix4(); + rotateZ1.makeRotationZ((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0); + + var rotateX2 = new THREE.Matrix4(); + rotateX2.makeRotationX(3.1415 / 2.0); + + var rotateY2 = new THREE.Matrix4(); + rotateY2.makeRotationY(-45.0 * 3.1415 / 180.0); + + var rotateZ2 = new THREE.Matrix4(); + rotateZ2.makeRotationY((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0); + + shaderPass1.uniforms["u_cwMat"].value = cwMat; + shaderPass1.uniforms["u_ccwMat"].value = ccwMat; + shaderPass1.uniforms["u_northMat"].value = northMat; + shaderPass1.uniforms["u_southMat"].value = southMat; + shaderPass1.uniforms["u_westMat"].value = westMat; + shaderPass1.uniforms["u_eastMat"].value = eastMat; + shaderPass1.uniforms["u_rotateX1"].value = rotateX1; + shaderPass1.uniforms["u_rotateY1"].value = rotateY1; + shaderPass1.uniforms["u_rotateZ1"].value = rotateZ1; + shaderPass1.uniforms["u_rotateX2"].value = rotateX2; + shaderPass1.uniforms["u_rotateY2"].value = rotateY2; + shaderPass1.uniforms["u_rotateZ2"].value = rotateZ2; + + composer1.render(); + composer2.render(); + composer3.render(); + } + } +} \ No newline at end of file From 098311604af6df4283651b0cc5c8dbbd6e57483d Mon Sep 17 00:00:00 2001 From: Joe Klinger Date: Wed, 3 May 2017 00:59:19 -0400 Subject: [PATCH 18/20] Turned on motion blur --- src/glsl/secondPass-frag.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/glsl/secondPass-frag.glsl b/src/glsl/secondPass-frag.glsl index ce352831..cb1071e4 100644 --- a/src/glsl/secondPass-frag.glsl +++ b/src/glsl/secondPass-frag.glsl @@ -7,7 +7,7 @@ #define SPHERE_TRACING true #define T_MAX 12.0 -// #define MOTION_BLUR true +#define MOTION_BLUR true varying vec2 f_uv; From 0b66e86ece7b61954690e65aedce807f52fe5f51 Mon Sep 17 00:00:00 2001 From: Joe Klinger Date: Wed, 3 May 2017 01:00:42 -0400 Subject: [PATCH 19/20] updated bundle --- build/bundle.js | 175 ++++++++++++++++++++++++++++++++++++++++---- build/bundle.js.map | 2 +- 2 files changed, 162 insertions(+), 15 deletions(-) diff --git a/build/bundle.js b/build/bundle.js index cd4e9f46..c789ae7e 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -64,10 +64,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - __webpack_require__(16); + __webpack_require__(18); var THREE = __webpack_require__(6); - var OrbitControls = __webpack_require__(17)(THREE); + var OrbitControls = __webpack_require__(19)(THREE); //Audio and Audio Analysis variables @@ -48016,15 +48016,14 @@ value: true }); exports.default = RayMarcher; - - var _proxy_geometry = __webpack_require__(5); - var THREE = __webpack_require__(6); var EffectComposer = __webpack_require__(8)(THREE); function RayMarcher(renderer, scene, camera) { - var composer = new EffectComposer(renderer); - var shaderPass = new EffectComposer.ShaderPass({ + + var target1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight); + var composer1 = new EffectComposer(renderer, target1); + var shaderPass1 = new EffectComposer.ShaderPass({ uniforms: { u_time: { type: 'f', @@ -48041,20 +48040,156 @@ u_aspect: { type: 'f', value: camera.aspect + }, + u_cwMat: { + type: 'm4v', + value: null + }, + u_ccwMat: { + type: 'm4v', + value: null + }, + u_northMat: { + type: 'm4v', + value: null + }, + u_southMat: { + type: 'm4v', + value: null + }, + u_westMat: { + type: 'm4v', + value: null + }, + u_eastMat: { + type: 'm4v', + value: null + }, + u_rotateX1: { + type: 'm4v', + value: null + }, + u_rotateY1: { + type: 'm4v', + value: null + }, + u_rotateZ1: { + type: 'm4v', + value: null + }, + u_rotateX2: { + type: 'm4v', + value: null + }, + u_rotateY2: { + type: 'm4v', + value: null + }, + u_rotateZ2: { + type: 'm4v', + value: null } }, vertexShader: __webpack_require__(14), fragmentShader: __webpack_require__(15) + }); + var composer2 = new EffectComposer(renderer); + var shaderPass2 = new EffectComposer.ShaderPass({ + uniforms: { + u_firstPass: { + type: 't', + value: null + }, + u_previousFrame: { + type: 't', + value: null + } + }, + vertexShader: __webpack_require__(14), + fragmentShader: __webpack_require__(16) + }); + shaderPass2.renderToScreen = true; + shaderPass2.material.uniforms.u_firstPass.value = composer1.writeBuffer.texture; + + var target3 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight); + var composer3 = new EffectComposer(renderer, target3); + var shaderPass3 = new EffectComposer.ShaderPass({ + uniforms: { + u_input: { + type: 't', + value: null + } + }, + vertexShader: __webpack_require__(14), + fragmentShader: __webpack_require__(17) }); - shaderPass.renderToScreen = true; - composer.addPass(shaderPass); + shaderPass2.material.uniforms.u_previousFrame.value = composer3.writeBuffer.texture; + shaderPass3.material.uniforms.u_input.value = composer1.writeBuffer.texture; + + composer1.addPass(shaderPass1); + composer2.addPass(shaderPass2); + composer3.addPass(shaderPass3); return { render: function render(buffer, clock) { - shaderPass.uniforms["u_time"].value = clock.getElapsedTime(); - composer.render(); - // console.log(composer); + shaderPass1.uniforms["u_time"].value = clock.getElapsedTime(); + + // Mandelbulb transformation uniforms + var angle = clock.getElapsedTime() / (4.0 * 3.1415); + + var cwMat = new THREE.Matrix4(); + cwMat.makeRotationY(angle); + + var ccwMat = new THREE.Matrix4(); + ccwMat.makeRotationY(-angle); + + var northMat = new THREE.Matrix4(); + northMat.makeRotationX(angle); + + var southMat = new THREE.Matrix4(); + southMat.makeRotationX(-angle); + + var eastMat = new THREE.Matrix4(); + eastMat.makeRotationZ(angle); + + var westMat = new THREE.Matrix4(); + westMat.makeRotationZ(-angle); + + var rotateX1 = new THREE.Matrix4(); + rotateX1.makeRotationX(3.1415 / 2.0); + + var rotateY1 = new THREE.Matrix4(); + rotateY1.makeRotationY(45.0 * 3.1415 / 180.0); + + var rotateZ1 = new THREE.Matrix4(); + rotateZ1.makeRotationZ(2.0 * clock.getElapsedTime() * 3.1415 / 180.0); + + var rotateX2 = new THREE.Matrix4(); + rotateX2.makeRotationX(3.1415 / 2.0); + + var rotateY2 = new THREE.Matrix4(); + rotateY2.makeRotationY(-45.0 * 3.1415 / 180.0); + + var rotateZ2 = new THREE.Matrix4(); + rotateZ2.makeRotationY(2.0 * clock.getElapsedTime() * 3.1415 / 180.0); + + shaderPass1.uniforms["u_cwMat"].value = cwMat; + shaderPass1.uniforms["u_ccwMat"].value = ccwMat; + shaderPass1.uniforms["u_northMat"].value = northMat; + shaderPass1.uniforms["u_southMat"].value = southMat; + shaderPass1.uniforms["u_westMat"].value = westMat; + shaderPass1.uniforms["u_eastMat"].value = eastMat; + shaderPass1.uniforms["u_rotateX1"].value = rotateX1; + shaderPass1.uniforms["u_rotateY1"].value = rotateY1; + shaderPass1.uniforms["u_rotateZ1"].value = rotateZ1; + shaderPass1.uniforms["u_rotateX2"].value = rotateX2; + shaderPass1.uniforms["u_rotateY2"].value = rotateY2; + shaderPass1.uniforms["u_rotateZ2"].value = rotateZ2; + + composer1.render(); + composer2.render(); + composer3.render(); } }; } @@ -48488,16 +48623,28 @@ /* 15 */ /***/ (function(module, exports) { - module.exports = "\r\n#define MAX_GEOMETRY_COUNT 100\r\n#define SPHERE_TRACING true\r\n#define T_MAX 10.0\r\n\r\n/* This is how I'm packing the data\r\nstruct geometry_t {\r\n vec3 position;\r\n float type;\r\n};\r\n*/\r\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\r\n// uniform int u_count;\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\nvec4 resColor;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t *****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\n//diagonal is the vector from the center of the box to the first quadrant corner\r\nfloat boxSDF(vec3 point, vec3 diagonal) {\r\n\tvec3 d = abs(point) - diagonal;\r\n \treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\r\n}\r\n\r\nfloat SDF_Mandlebulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i=0; i<4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n resColor = trap;\r\n\r\n return 0.25*log(m)*sqrt(m)/dz;\r\n}\r\n\r\n//Operators:\r\n\r\nfloat intersection(float d1, float d2)\r\n{\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 )\r\n{\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2)\r\n{\r\n return min(d1,d2);\r\n}\r\n\r\n// Returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform(vec3 point, mat4 trans)\r\n{\r\n\t// Columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\n// Return the distance of the closest object in the scene\r\nfloat sceneMap( vec3 pos ) {\r\n\treturn SDF_Sphere( pos, 1.0 );\r\n}\r\n\r\nfloat mod(int num1, int num2)\r\n{\r\n\tint div = num1/num2;\r\n\treturn float(num1 - div*num2);\r\n}\r\n\r\nint sceneNum()\r\n{\r\n\tfloat x = u_time;\r\n\tfloat cycle = 124.0;\r\n\tfloat fps = 6.0;\r\n\tfloat t = mod(x, cycle);\r\n\tif(t <= 42.0) { return 2; }\r\n\telse if(t <= 80.0) { return 1; }\r\n\telse { return 3; }\r\n}\r\n\r\nfloat sceneMap2( vec3 pos ){\r\n\r\n\tfloat t = u_time/4.0;\r\n\tint sceneNumber = sceneNum();\r\n\r\n\tfloat angle = 2.0*t/(2.0*3.1415);\r\n\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\r\n\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\r\n\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\r\n\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\r\n\r\n\tmat4 northMat = mat4(1.0); \r\n\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\r\n\tmat4 southMat = mat4(1.0); \r\n\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\r\n\tmat4 westMat = mat4(1.0); \r\n\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\r\n\tmat4 eastMat = mat4(1.0); \r\n\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\r\n\r\n\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\r\n\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\r\n\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\r\n\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\r\n\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\r\n\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\r\n\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\r\n\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\r\n\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\r\n\r\n\tif(sceneNumber == 1)\r\n\t{\r\n\t\t//SCENE 01------------------------------------------------------------\r\n\t\tfloat dist1;\r\n\t\t//vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat);\r\n\t\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), cwMat), northMat);\t\r\n\t\tfloat bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1));\r\n\t\tif(bb1 < .015)\r\n\t\t{\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist1 = SDF_Mandlebulb(newPos1, power);\r\n\t\t}\t\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist1 = bb1;\r\n\t\t}\r\n\r\n\t\tfloat dist2;\r\n\t\t//vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat);\r\n\t\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), ccwMat), eastMat);\t\r\n\t\tfloat bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1));\r\n\t\tif(bb2 < .015)\r\n\t\t{\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist2 = SDF_Mandlebulb(newPos2, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist2 = bb2;\r\n\t\t}\r\n\r\n\t\tfloat dist3;\r\n\t\t// vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat);\r\n\t\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat);\t\r\n\t\tfloat bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb3 < .015)\r\n\t\t{\r\n\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist3 = SDF_Mandlebulb(newPos3, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist3 = bb3;\r\n\t\t}\r\n\r\n\t\treturn un(dist1, un(dist2, dist3));\r\n\t}\r\n\telse if(sceneNumber == 2)\r\n\t{\r\n\t\t//SCENE 02------------------------------------------------------------\r\n\t\tfloat dist4;\r\n\t\tmat4 rotateX = mat4(1.0); rotateX[1][1] = 0.0; rotateX[1][2] = 1.0; rotateX[2][1] = -1.0; rotateX[2][2] = 0.0; //rotate 90 degress about x-axis\r\n\t\tfloat angY = 45.0*3.1415/180.0;\r\n\t\tmat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis\r\n\t\tfloat angZ = (2.0*u_time)*3.1415/180.0;\r\n\t\tmat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis\r\n\t\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \r\n\t\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX);\t\r\n\t\tfloat bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb4 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist4 = SDF_Mandlebulb(newPos4, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist4 = bb4;\r\n\t\t}\r\n\r\n\t\treturn dist4;\r\n\t}\r\n\telse \r\n\t{\r\n\t\t//SCENE 03------------------------------------------------------------\r\n\t\tfloat dist5;\r\n\t\tmat4 rotateX2 = mat4(1.0); rotateX2[1][1] = 0.0; rotateX2[1][2] = 1.0; rotateX2[2][1] = -1.0; rotateX2[2][2] = 0.0; //rotate 90 degress about x-axis\r\n\t\tfloat angY2 = -45.0*3.1415/180.0;\r\n\t\tmat4 rotateY2 = mat4(1.0); rotateY2[0][0] = cos(angY2); rotateY2[0][2] = -sin(angY2); rotateY2[2][0] = sin(angY2); rotateY2[2][2] = cos(angY2); //rotate 45 degrees about y-axis\r\n\t\tfloat angZ2 = (2.0*u_time)*3.1415/180.0;\r\n\t\tmat4 rotateZ2 = mat4(1.0); rotateZ2[0][0] = cos(angZ2); rotateZ2[0][2] = -sin(angZ2); rotateZ2[2][0] = sin(angZ2); rotateZ2[2][2] = cos(angZ2); //spin about y-axis\r\n\t\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), rotateY2), rotateX2), rotateZ2);\t\r\n\t\tfloat bb5 = SDF_Sphere(newPos5, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\r\n\t\tif(bb5 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist5 = SDF_Mandlebulb(newPos5, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist5 = bb5;\r\n\t\t}\r\n\r\n\t\treturn dist5;\r\n\t}\r\n\t\r\n\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\r\n\t//return dist3;\r\n\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\nvec3 computeNormal( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\r\n\t\t\t\t\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\r\n\t\t\t\t\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\r\n\treturn normal;\r\n}\r\n\r\n// Check for intersection with the scene for increasing t-values\r\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\r\n\tfloat dist;\r\n\tfloat t = 0.01;\r\n\tfor(int i = 0; i < 500; i++) {\r\n\t\tfloat dist = sceneMap2(origin + t * direction);\r\n\t\tif(dist < 0.0001) {\r\n\t\t\treturn vec2(t, 1.0); // intersection\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn vec2(0.0, -1.0); // no intersection\r\n}\r\n\r\n\r\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\r\n\tfloat dot = dot(normalize(toCam + toLight), normal);\r\n\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\r\n}\r\n\r\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\r\nfloat ComputeAO( vec3 pos, vec3 normal ) {\r\n\tfloat tStep = 0.0025;\r\n\tfloat t = 0.0;\r\n\tfloat ao = 1.0;\r\n\tfloat diff = 0.0;\r\n\tfloat k = 72.0;\r\n\tfor(int i = 0; i < 5; i++) {\r\n\t\tvec3 sample = pos + t * normal;\r\n\t\tfloat dist = sceneMap2( sample );\r\n\t\tdiff += pow(0.5, float (i)) * (t - dist);\r\n\t\tt += tStep;\r\n\t}\r\n\tao -= clamp(k * diff, 0.0, 1.0);\r\n\treturn ao;\r\n}\r\n\r\n\r\nvec3 backgroundColor()\r\n{\r\n\tint sn = sceneNum();\r\n\tfloat darken; \r\n\tif(sn == 1)\r\n\t{\r\n\t\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\r\n\t\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\r\n\t}\r\n\telse if(sn == 2)\r\n\t{\r\n\t\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\r\n\t\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\r\n\t}\r\n\t\r\n\tdarken = clamp(darken, 0.2, 1.0);\r\n\r\n\tvec3 a = vec3(0.5, 0.5, 0.5);\r\n\tvec3 b = vec3(0.5, 0.5, 0.5);\r\n\tvec3 c = vec3(2.0, 1.0, 1.0);\r\n\tvec3 d = vec3(0.5, 0.2, 0.25);\r\n\tfloat t = abs(sin(u_time/12.0));\r\n\tvec3 color = a + b*cos(6.28*(c*t + d));\r\n\r\n\treturn darken*color;\r\n}\r\n\r\n\r\nvoid main() {\r\n\t\r\n\t/** Raycasting **/\r\n\t\r\n\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\r\n\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\r\n\t\t\t\t\t\t\t\tgl_FragCoord.y / u_resolution.y) - 1.0;\r\n\r\n\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\r\n\t//vec3 cameraPos = vec3(1, -4, 2);\r\n\t//vec3 cameraPos = vec3(1, 0, 1);\r\n\t\r\n\t// Circle the origin (0, 0, 0)\r\n\t// cameraPos.x = sin(u_time) * 10.0;\r\n\t// cameraPos.z = cos(u_time) * 10.0;\r\n\t\r\n\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\r\n\t\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos);\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\r\n\t\r\n\t// Perform the raymarch\r\n\tvec3 direction = normalize(point_World - cameraPos);\r\n\tvec2 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\t/** Shading and lighting **/\r\n\t\r\n\tif(isect.y > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormal( isectPos );\r\n\t\t\r\n\t\t// Lighting\r\n\t\tvec3 baseMaterial = vec3(0.1, 0.2, 0.2);\r\n\t\tvec3 trapColor;\r\n\t\tint sn = sceneNum();\r\n\t\tif(sn == 1)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(\r\n\t\t\t\tresColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.8), \r\n\t\t\t\tresColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), \r\n\t\t\t\tresColor.z+(cos((u_time)/2.0-isectPos.x)*0.2));\r\n\t\t}\r\n\t\telse if(sn == 2)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(resColor) + vec3(0.4);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\ttrapColor = vec3(0.0, resColor.y+0.4, resColor.z+0.4);\r\n\t\t}\r\n\t\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\r\n\t\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\r\n\t\t\r\n\t\tvec3 toSun = normalize(sunPos - isectPos);\r\n\t\t\r\n\t\tnormal = -normal;\r\n\t\t\r\n\t\t// Visibility test\r\n\t\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\r\n\t\t// float vis = 1.0;\r\n\t\t\r\n\t\t// if(shadowTest.y > 0.0) { // something is blocking this point\r\n\t\t// \tvis = 0.0;\r\n\t\t// }\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t// Phong-ish shading for now\r\n\t\tfloat spec = SpecHighlight( -look, toSun, normal);\r\n\t\t\r\n\t\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\r\n\t\tfloat ao = ComputeAO(isectPos, normal);\r\n\t\t\r\n\t\t// Apply lambertian shading - for now\r\n\t\t\r\n\t\t//gl_FragColor = ao*vec4(baseMaterial, 1.0);\r\n\t\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\r\n\t\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\r\n\t} else {\r\n\t\t// Background color\r\n\t\tgl_FragColor = vec4(backgroundColor(), 1);\r\n\t}\r\n}\r\n" + module.exports = "/* \r\n\tCode written by Joseph Klinger and Tabatha Hickman\r\n\tUniversity of Pennsylvania\r\n\tCIS 700 Instructor: Rachel Hwang\r\n\tMay 2017\r\n*/\r\n\r\n#define SPHERE_TRACING true\r\n#define T_MAX 10.0\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\nuniform mat4 u_cwMat;\r\nuniform mat4 u_ccwMat;\r\nuniform mat4 u_northMat;\r\nuniform mat4 u_southMat;\r\nuniform mat4 u_westMat;\r\nuniform mat4 u_eastMat;\r\nuniform mat4 u_rotateX1;\r\nuniform mat4 u_rotateY1;\r\nuniform mat4 u_rotateZ1;\r\nuniform mat4 u_rotateX2;\r\nuniform mat4 u_rotateY2;\r\nuniform mat4 u_rotateZ2;\r\n\r\n\r\nvec4 resColor;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t \t\t\t\t\t\t\t\t\t\t\t*****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\n// Taken from IQ's realtime ShaderToy implementation here: https://www.shadertoy.com/view/ltfSWn\r\nfloat SDF_Mandelbulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i = 0; i < 4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n resColor = trap;\r\n\r\n return 0.25 * log(m) * sqrt(m) / dz;\r\n}\r\n\r\n// SDF Operators:\r\nfloat intersection(float d1, float d2) {\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 ) {\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2) {\r\n return min(d1,d2);\r\n}\r\n\r\n// Returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform( vec3 point, mat4 trans ) {\r\n\t//columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\nfloat mod(int num1, int num2)\r\n{\r\n\tint div = num1/num2;\r\n\treturn float(num1 - div*num2);\r\n}\r\n\r\n// Decide which scene to display (time - dependent)\r\nint sceneNum()\r\n{\r\n\tfloat x = u_time;\r\n\tfloat cycle = 124.0;\r\n\tfloat fps = 6.0;\r\n\tfloat t = mod(x, cycle);\r\n\tif(t <= 42.0) { return 2; }\r\n\telse if(t <= 80.0) { return 1; }\r\n\telse { return 3; }\r\n}\r\n\r\n// Estimate the distance to the objects in the scene depending on the sceneNum() (see above)\r\nfloat sceneMap( vec3 pos ) {\r\n\tfloat t = u_time/4.0;\r\n\tint sceneNumber = sceneNum();\r\n\r\n\tif(sceneNumber == 1)\r\n\t{\r\n\t\t//SCENE 01------------------------------------------------------------\r\n\t\tfloat dist1;\r\n\t\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), u_cwMat), u_northMat);\t\r\n\t\tfloat bb1 = SDF_Sphere(newPos1, 1.1);\r\n\t\tif(bb1 < .015)\r\n\t\t{\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist1 = SDF_Mandelbulb(newPos1, power);\r\n\t\t}\t\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist1 = bb1;\r\n\t\t}\r\n\r\n\t\tfloat dist2;\r\n\t\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), u_ccwMat), u_eastMat);\t\r\n\t\tfloat bb2 = SDF_Sphere(newPos2, 1.1);\r\n\t\tif(bb2 < .015)\r\n\t\t{\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist2 = SDF_Mandelbulb(newPos2, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist2 = bb2;\r\n\t\t}\r\n\r\n\t\tfloat dist3;\r\n\t\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), u_cwMat), u_westMat);\t\r\n\t\tfloat bb3 = SDF_Sphere(newPos3, 1.1);\r\n\t\tif(bb3 < .015)\r\n\t\t{\r\n\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist3 = SDF_Mandelbulb(newPos3, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist3 = bb3;\r\n\t\t}\r\n\r\n\t\treturn un(dist1, un(dist2, dist3));\r\n\t}\r\n\telse if(sceneNumber == 2)\r\n\t{\r\n\t\t//SCENE 02------------------------------------------------------------\r\n\t\tfloat dist4;\r\n\t\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \r\n\t\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), u_rotateY1), u_rotateZ1), u_rotateX1);\t\r\n\t\tfloat bb4 = SDF_Sphere(newPos4, 1.1);\r\n\t\tif(bb4 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist4 = SDF_Mandelbulb(newPos4, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist4 = bb4;\r\n\t\t}\r\n\r\n\t\treturn dist4;\r\n\t}\r\n\telse \r\n\t{\r\n\t\t//SCENE 03------------------------------------------------------------\r\n\t\tfloat dist5;\r\n\t\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), u_rotateY2), u_rotateX2), u_rotateZ2);\t\r\n\t\tfloat bb5 = SDF_Sphere(newPos5, 1.1);\r\n\t\tif(bb5 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist5 = SDF_Mandelbulb(newPos5, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist5 = bb5;\r\n\t\t}\r\n\r\n\t\treturn dist5;\r\n\t}\r\n}\r\n\r\nvec3 backgroundColor() {\r\n\tint sn = sceneNum();\r\n\tfloat darken; \r\n\tif(sn == 1)\r\n\t{\r\n\t\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\r\n\t\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\r\n\t}\r\n\telse if(sn == 2)\r\n\t{\r\n\t\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\r\n\t\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\r\n\t}\r\n\t\r\n\tdarken = clamp(darken, 0.2, 1.0);\r\n\r\n\tvec3 a = vec3(0.5, 0.5, 0.5);\r\n\tvec3 b = vec3(0.5, 0.5, 0.5);\r\n\tvec3 c = vec3(2.0, 1.0, 1.0);\r\n\tvec3 d = vec3(0.5, 0.2, 0.25);\r\n\tfloat t = abs(sin(u_time/12.0));\r\n\tvec3 color = a + b*cos(6.28*(c*t + d));\r\n\r\n\treturn darken*color;\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\n// Note: this method is slightly less accurate than sampling the scene at pos - epsilon, but because that is an expensive operation for the mandelbulb, we avoid it here\r\nvec3 computeNormalFast( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tfloat sampleAtPos = sceneMap(pos);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap(pos + point.xyy) - sampleAtPos,\r\n\t\t\t\t\tsceneMap(pos + point.yxy) - sampleAtPos,\r\n\t\t\t\t\tsceneMap(pos + point.yyx) - sampleAtPos));\r\n\treturn normal;\r\n}\r\n\r\n// Taken from a presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\r\nfloat ComputeAO( vec3 pos, vec3 normal ) {\r\n\tfloat tStep = 0.0025;\r\n\tfloat diff = 0.0;\r\n\tfloat k = 34.0;\r\n\tfor(float i = 1.0; i <= 5.0; i += 1.0) {\r\n\t\tvec3 sample = pos + (i * tStep) * normal;\r\n\t\tfloat dist = sceneMap( sample );\r\n\t\tdiff += pow(0.5, i) * ((i * tStep) - dist);\r\n\t}\r\n\treturn 1.0 - clamp(k * diff, 0.0, 0.9);\r\n}\r\n\r\n// Convert a fragment coordinate to normalized device coordinates\r\nvec2 FragCoordToNDC( vec4 fragCoord ) {\r\n\treturn 2.0 * vec2(fragCoord.x / u_resolution.x,\r\n\t\t\t\t\t fragCoord.y / u_resolution.y) - 1.0;\r\n}\r\n\r\n// Return the direction of a ray cast through the given point in NDC\r\n// This function includes the implementation of the camera; changes to the camera should be made here\r\nvec3 Raycast( vec2 p_ndc, vec3 cameraPos ) {\r\n\t\r\n\tfloat len = 10.0;\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos); // Assume we are looking towards (0, 0, 0)\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = p_ndc.x * H + p_ndc.y * V;\r\n\t\r\n\t// Return the direction\r\n\treturn normalize(point_World - cameraPos);\r\n}\r\n\r\n// Referencing the following report: http://celarek.at/wp/wp-content/uploads/2014/05/realTimeFractalsReport.pdf\r\nvec3 raymarchScene( vec3 origin, vec3 direction ) {\r\n\t// Basic Raymarching function: \r\n\tfloat t = 0.01;\r\n\tvec3 result = vec3(0.0);\r\n\t\r\n\tfor(int i = 1; i <= 250; i++) {\r\n\t\tfloat dist = sceneMap(origin + t * direction);\r\n\t\t\r\n\t\tif(abs(dist) < 0.0002) {\r\n\t\t\tresult = vec3(t, float (i) / 1000.0, 1.0);\r\n\t\t\tbreak;\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tresult = vec3(T_MAX, float (i) / 1000.0, 0.0);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn result;\r\n}\r\n\r\nvoid main() {\r\n\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\r\n\tvec2 point_NDC = FragCoordToNDC(gl_FragCoord);\r\n\tvec3 direction = Raycast(point_NDC, cameraPos);\r\n\t\r\n\tvec3 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\tif(isect.z > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormalFast( isectPos );\r\n\t\tnormal = -normal;\r\n\t\t\r\n\t\t// Animated color using orbit traps: see the Mandelbulb SDF by IQ above\r\n\t\tvec3 trapColor;\r\n\t\t\r\n\t\tint sn = sceneNum();\r\n\t\tif(sn == 1)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(\r\n\t\t\t\tresColor.x-abs(sin((u_time) / 2.0 + isectPos.z) * 0.8), \r\n\t\t\t\tresColor.y-(cos((u_time) / 8.0 + isectPos.y) * 0.5), \r\n\t\t\t\tresColor.z+(cos((u_time) / 2.0 - isectPos.x) * 0.2));\r\n\t\t}\r\n\t\telse if(sn == 2)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(resColor) + vec3(0.4);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\ttrapColor = vec3(0.0, resColor.y + 0.4, resColor.z + 0.4);\r\n\t\t}\r\n\t\t\r\n\t\ttrapColor.r *= 0.01;\r\n\t\t\r\n\t\t// Two methods to compute AO:\r\n\t\tfloat ao = ComputeAO(isectPos, normal);\r\n\t\t// float fakeAO = 1.0 - clamp(isect.y, 0.0, 0.9);\r\n\t\t\r\n\t\tgl_FragColor = ao * vec4(trapColor, 1);\r\n\t\t// gl_FragColor = fakeAO * vec4(trapColor, 1);\r\n\t} else {\r\n\t\tgl_FragColor = vec4(backgroundColor(), 1);\r\n\t}\r\n}\r\n" /***/ }), /* 16 */ +/***/ (function(module, exports) { + + module.exports = "/* \r\n\tCode written by Joseph Klinger and Tabatha Hickman\r\n\tUniversity of Pennsylvania\r\n\tCIS 700 Instructor: Rachel Hwang\r\n\tMay 2017\r\n*/\r\n\r\n#define SPHERE_TRACING true\r\n#define T_MAX 12.0\r\n#define MOTION_BLUR true\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform sampler2D u_firstPass;\r\nuniform sampler2D u_previousFrame;\r\n\r\n// The sole purpose of this pass is to compute motion blur between the current and previous frames\r\nvoid main() {\r\n\t#ifdef MOTION_BLUR\r\n\t\tfor(float w = 0.0; w <= 1.0; w += 0.2) {\r\n\t\t\tgl_FragColor += (1.0 - w) * texture2D(u_firstPass, f_uv) + w * texture2D(u_previousFrame, f_uv);\r\n\t\t}\r\n\t\tgl_FragColor /= 1.0 / 0.2; // divide by the number of samples (1 / stepSize)\r\n\t#else\r\n\t\tgl_FragColor = texture2D(u_firstPass, f_uv);\r\n\t#endif\r\n}\r\n" + +/***/ }), +/* 17 */ +/***/ (function(module, exports) { + + module.exports = "/* \r\n\tCode written by Joseph Klinger and Tabatha Hickman\r\n\tUniversity of Pennsylvania\r\n\tCIS 700 Instructor: Rachel Hwang\r\n\tMay 2017\r\n*/\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform sampler2D u_input;\r\n\r\nvoid main() {\r\n\tgl_FragColor = texture2D(u_input, f_uv);\r\n}\r\n" + +/***/ }), +/* 18 */ /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__.p + "index.html"; /***/ }), -/* 17 */ +/* 19 */ /***/ (function(module, exports) { module.exports = function( THREE ) { diff --git a/build/bundle.js.map b/build/bundle.js.map index 09cfdd24..525bc541 100644 --- a/build/bundle.js.map +++ b/build/bundle.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 7b6f060d86f4e785c168","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/rayMarch-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","listener","AudioListener","sound","PositionalAudio","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","audioLoader","AudioLoader","load","buffer","setBuffer","setLoop","setVolume","play","aspect","updateProjectionMatrix","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","composer","shaderPass","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","vertexShader","fragmentShader","renderToScreen","addPass","getElapsedTime"],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;;;ACjCA;;;;AACA;;;;AACA;;;;AACA;;;;;;AARA,oBAAAA,CAAQ,EAAR;;AAEA,KAAMC,QAAQ,mBAAAD,CAAQ,CAAR,CAAd;AACA,KAAME,gBAAgB,mBAAAF,CAAQ,EAAR,EAAgCC,KAAhC,CAAtB;;AAOA;;AAEA;AACA,KAAIE,WAAW,IAAIF,MAAMG,aAAV,EAAf;;AAEA;AACA,KAAIC,QAAQ,IAAIJ,MAAMK,eAAV,CAA2BH,QAA3B,CAAZ;;AAEA,KAAII,cAAc,IAAIN,MAAMM,WAAV,CAAsB,CAAtB,EAAyB,CAAzB,EAA4B,CAA5B,CAAlB;AACA,KAAIC,iBAAiB,IAAIP,MAAMO,cAAV,CAAyB,CAAzB,EAA4B,EAA5B,EAAgC,EAAhC,CAArB;AACA,KAAIC,eAAe,IAAIR,MAAMQ,YAAV,CAAuB,CAAvB,EAA0B,CAA1B,CAAnB;;AAEA,KAAIC,QAAQ,IAAIT,MAAMU,KAAV,EAAZ;;AAEAC,QAAOC,gBAAP,CAAwB,MAAxB,EAAgC,YAAW;AACvC,SAAIC,QAAQ,uBAAZ;AACAA,WAAMC,OAAN,CAAc,CAAd;AACAD,WAAME,UAAN,CAAiBC,KAAjB,CAAuBC,QAAvB,GAAkC,UAAlC;AACAJ,WAAME,UAAN,CAAiBC,KAAjB,CAAuBE,IAAvB,GAA8B,KAA9B;AACAL,WAAME,UAAN,CAAiBC,KAAjB,CAAuBG,GAAvB,GAA6B,KAA7B;AACAC,cAASC,IAAT,CAAcC,WAAd,CAA0BT,MAAME,UAAhC;;AAEA,SAAIQ,QAAQ,IAAIvB,MAAMwB,KAAV,EAAZ;AACA,SAAIC,SAAS,IAAIzB,MAAM0B,iBAAV,CAA6B,EAA7B,EAAiCf,OAAOgB,UAAP,GAAkBhB,OAAOiB,WAA1D,EAAuE,GAAvE,EAA4E,IAA5E,CAAb;AACA,SAAIC,WAAW,IAAI7B,MAAM8B,aAAV,CAAyB,EAAEC,WAAW,IAAb,EAAzB,CAAf;AACAF,cAASG,aAAT,CAAuBrB,OAAOsB,gBAA9B;AACAJ,cAASK,OAAT,CAAiBvB,OAAOgB,UAAxB,EAAoChB,OAAOiB,WAA3C;AACAC,cAASM,aAAT,CAAuB,QAAvB,EAAiC,GAAjC;AACAf,cAASC,IAAT,CAAcC,WAAd,CAA0BO,SAASd,UAAnC;;AAEA,SAAIqB,WAAW,IAAInC,aAAJ,CAAkBwB,MAAlB,EAA0BI,SAASd,UAAnC,CAAf;AACAqB,cAASC,aAAT,GAAyB,IAAzB;AACAD,cAASE,UAAT,GAAsB,IAAtB;AACAF,cAASG,WAAT,GAAuB,GAAvB;AACAH,cAASI,SAAT,GAAqB,GAArB;AACAJ,cAASK,QAAT,GAAoB,GAApB;;AAGA,SAAIC,cAAc,IAAI1C,MAAM2C,WAAV,EAAlB;;AAEA;AACAD,iBAAYE,IAAZ,CAAkB,0BAAlB,EAA8C,UAAUC,MAAV,EAAmB;AAC7DzC,eAAM0C,SAAN,CAAiBD,MAAjB;AACAzC,eAAM2C,OAAN,CAAc,IAAd;AACA3C,eAAM4C,SAAN,CAAgB,GAAhB;AACA5C,eAAM6C,IAAN;AACH,MALD;;AAOAtC,YAAOC,gBAAP,CAAwB,QAAxB,EAAkC,YAAW;AACzCa,gBAAOyB,MAAP,GAAgBvC,OAAOgB,UAAP,GAAoBhB,OAAOiB,WAA3C;AACAH,gBAAO0B,sBAAP;AACAtB,kBAASK,OAAT,CAAiBvB,OAAOgB,UAAxB,EAAoChB,OAAOiB,WAA3C;AACH,MAJD;;AAMA;;AAEA,SAAIwB,UAAU;AACVC,mBAAU;AADA,MAAd;;AAIA;;AAEA9B,WAAM+B,GAAN,CAAU,IAAItD,MAAMuD,UAAV,CAAqB,EAArB,CAAV;AACAhC,WAAM+B,GAAN,CAAU,IAAItD,MAAMwD,gBAAV,CAA2B,QAA3B,EAAqC,CAArC,CAAV;;AAEA,SAAIC,gBAAgB,8BAApB;;AAEA,SAAIC,UAAU,IAAI1D,MAAM2D,IAAV,CAAerD,WAAf,gCAAd;AACA,SAAIsD,aAAa,IAAI5D,MAAM2D,IAAV,CAAepD,cAAf,gCAAjB;AACA,SAAIsD,WAAW,IAAI7D,MAAM2D,IAAV,CAAenD,YAAf,gCAAf;;AAEAkD,aAAQzC,QAAR,CAAiB6C,GAAjB,CAAqB,CAAC,CAAtB,EAAyB,CAAzB,EAA4B,CAA5B;AACAD,cAAS5C,QAAT,CAAkB6C,GAAlB,CAAsB,CAAtB,EAAyB,CAAzB,EAA4B,CAA5B;;AAEAL,mBAAcH,GAAd,CAAkBI,OAAlB;AACAD,mBAAcH,GAAd,CAAkBM,UAAlB;AACAH,mBAAcH,GAAd,CAAkBO,QAAlB;;AAEAtC,WAAM+B,GAAN,CAAUG,cAAcM,KAAxB;;AAEAtC,YAAOR,QAAP,CAAgB6C,GAAhB,CAAoB,CAApB,EAAuB,EAAvB,EAA2B,EAA3B;AACArC,YAAOuC,MAAP,CAAc,IAAIhE,MAAMiE,OAAV,CAAkB,CAAlB,EAAoB,CAApB,EAAsB,CAAtB,CAAd;AACA7B,cAAS8B,MAAT,CAAgBJ,GAAhB,CAAoB,CAApB,EAAsB,CAAtB,EAAwB,CAAxB;;AAEA,SAAIK,aAAa,0BAAetC,QAAf,EAAyBN,KAAzB,EAAgCE,MAAhC,CAAjB;;AAEA,MAAC,SAAS2C,IAAT,GAAgB;AACbhC,kBAASiC,MAAT;AACAxD,eAAMyD,KAAN;AACAb,uBAAcY,MAAd;AACA,aAAIjB,QAAQC,QAAR,KAAqB,gBAAzB,EAA2C;AACvCxB,sBAAS0C,MAAT,CAAgBhD,KAAhB,EAAuBE,MAAvB;AACH,UAFD,MAEO,IAAI2B,QAAQC,QAAR,KAAqB,cAAzB,EAAyC;AAC5Cc,wBAAWI,MAAX,CAAkBd,cAAcZ,MAAhC,EAAwCpC,KAAxC;AACH;AACDI,eAAM2D,GAAN;AACAC,+BAAsBL,IAAtB;AACH,MAXD;AAYH,EApFD,E;;;;;;ACxBA;AACA,8C;;;;;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;;AAGD;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,SAAQ,OAAO;AACf;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA,qEAAoE,iCAAiC;;AAErG;;AAEA;AACA;;;;AAIA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA,WAAU,iDAAiD,gBAAgB,uBAAuB,2BAA2B,qBAAqB,qBAAqB,GAAG,gBAAgB,yBAAyB,2BAA2B,gBAAgB,wBAAwB,yBAAyB,+BAA+B,GAAG,sBAAsB,0BAA0B,uBAAuB,2BAA2B,4BAA4B,gBAAgB,iBAAiB,uBAAuB,qBAAqB,kBAAkB,iBAAiB,GAAG;;;AAGlkB;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;;AAEA;AACA;AACA,4C;AACA,YAAW;AACX;AACA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AA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AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA,sBAAqB,mGAAmG,aAAa,2CAA2C,mBAAmB,SAAS,KAAK,4BAA4B,YAAY,gBAAgB,oCAAoC,WAAW,qCAAqC,gBAAgB,uBAAuB,iBAAiB,oCAAoC,eAAe,4BAA4B,uCAAuC,cAAc,iBAAiB;AAC1iB,mBAAkB,iBAAiB,oCAAoC,gBAAgB,mCAAmC,WAAW,YAAY,uBAAuB,qBAAqB,qBAAqB,EAAE,qCAAqC,2BAA2B,YAAY,WAAW,uBAAuB,iBAAiB,oCAAoC,UAAU,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EA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,sBAAsB;;AAE5D;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4BAA2B;;;AAG3B;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC;;AAEvC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,kBAAiB;;AAEjB;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,OAAM;;AAEN;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,iBAAgB;;AAEhB;;AAEA;;AAEA;AACA;AACA,uDAAsD;;AAEtD;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG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AiH,sDAAsD,oLAAoL,yJAAyJ,GAAG;;AAEjjB,oJAAmJ,sDAAsD,mMAAmM,6PAA6P,4TAA4T,WAAW;;AAEh9B,0CAAyC,wBAAwB,+QAA+Q,4EAA4E,iDAAiD,0KAA0K,yDAAyD,6IAA6I;;AAE7zB,wCAAuC,sBAAsB,0MAA0M,wKAAwK,mCAAmC,yKAAyK;;AAE3nB,2CAA0C,yKAAyK,8EAA8E,GAAG;;AAEpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;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;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;A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AEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,uBAAuB;;AAE7D;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,qBAAoB,sBAAsB;;AAE1C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,4BAA2B,gBAAgB;;AAE3C;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,qBAAoB,sBAAsB;;AAE1C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,4BAA2B,kBAAkB;;AAE7C;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,8CAA6C,OAAO;;AAEpD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH,0BAAyB;;AAEzB;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,oBAAmB;AACnB,mBAAkB;AAClB,kBAAiB;AACjB;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,qBAAoB,0BAA0B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,qBAAoB,4BAA4B;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA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A;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;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;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,sBAAqB,eAAe;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;AAEA,wCAAuC,SAAS;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A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EA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sCAAqC;AACrC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;AACA,gDAA+C;;AAE/C;;AAEA;;AAEA;;AAEA;AACA,8CAA6C;;AAE7C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 7b6f060d86f4e785c168","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\n//Audio and Audio Analysis variables\r\n \r\n//Create an AudioListener and add it to the camera\r\nvar listener = new THREE.AudioListener();\r\n \r\n// create a global audio source\r\nvar sound = new THREE.PositionalAudio( listener );\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n\r\n var audioLoader = new THREE.AudioLoader();\r\n \r\n //Load a sound and set it as the Audio object's buffer\r\n audioLoader.load( 'Dubstep_Sub-Mix_2016.mp3', function( buffer ) {\r\n sound.setBuffer( buffer );\r\n sound.setLoop(true);\r\n sound.setVolume(1.0);\r\n sound.play();\r\n }); \r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n // var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n // gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
      \\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
      \\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
      The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
      \\n \\n
      \\n\\n
      \",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nimport {PROXY_BUFFER_SIZE} from './proxy_geometry'\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n var composer = new EffectComposer(renderer);\r\n var shaderPass = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/rayMarch-frag.glsl')\r\n \r\n });\r\n shaderPass.renderToScreen = true;\r\n composer.addPass(shaderPass);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n composer.render();\r\n // console.log(composer);\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"\\r\\n#define MAX_GEOMETRY_COUNT 100\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 10.0\\r\\n\\r\\n/* This is how I'm packing the data\\r\\nstruct geometry_t {\\r\\n vec3 position;\\r\\n float type;\\r\\n};\\r\\n*/\\r\\n// uniform vec4 u_buffer[MAX_GEOMETRY_COUNT];\\r\\n// uniform int u_count;\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\nvec4 resColor;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t *****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\n//diagonal is the vector from the center of the box to the first quadrant corner\\r\\nfloat boxSDF(vec3 point, vec3 diagonal) {\\r\\n\\tvec3 d = abs(point) - diagonal;\\r\\n \\treturn min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));\\r\\n}\\r\\n\\r\\nfloat SDF_Mandlebulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i=0; i<4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n resColor = trap;\\r\\n\\r\\n return 0.25*log(m)*sqrt(m)/dz;\\r\\n}\\r\\n\\r\\n//Operators:\\r\\n\\r\\nfloat intersection(float d1, float d2)\\r\\n{\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 )\\r\\n{\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2)\\r\\n{\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n// Returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform(vec3 point, mat4 trans)\\r\\n{\\r\\n\\t// Columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\n// Return the distance of the closest object in the scene\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\treturn SDF_Sphere( pos, 1.0 );\\r\\n}\\r\\n\\r\\nfloat mod(int num1, int num2)\\r\\n{\\r\\n\\tint div = num1/num2;\\r\\n\\treturn float(num1 - div*num2);\\r\\n}\\r\\n\\r\\nint sceneNum()\\r\\n{\\r\\n\\tfloat x = u_time;\\r\\n\\tfloat cycle = 124.0;\\r\\n\\tfloat fps = 6.0;\\r\\n\\tfloat t = mod(x, cycle);\\r\\n\\tif(t <= 42.0) { return 2; }\\r\\n\\telse if(t <= 80.0) { return 1; }\\r\\n\\telse { return 3; }\\r\\n}\\r\\n\\r\\nfloat sceneMap2( vec3 pos ){\\r\\n\\r\\n\\tfloat t = u_time/4.0;\\r\\n\\tint sceneNumber = sceneNum();\\r\\n\\r\\n\\tfloat angle = 2.0*t/(2.0*3.1415);\\r\\n\\tmat4 cwMat = mat4(1.0); //transform for moving clockwise\\r\\n\\tcwMat[0][0] = cos(angle); cwMat[0][2] = -sin(angle); cwMat[2][0] = sin(angle); cwMat[2][2] = cos(angle); //rotating about y-axis, based on utime\\r\\n\\tmat4 ccwMat = mat4(1.0); //transform for moving counterclockwise\\r\\n\\tccwMat[0][0] = cos(-angle); ccwMat[0][2] = -sin(-angle); ccwMat[2][0] = sin(-angle); ccwMat[2][2] = cos(-angle); //rotating about y-axis, based on utime\\r\\n\\r\\n\\tmat4 northMat = mat4(1.0); \\r\\n\\tnorthMat[1][1] = cos(angle); northMat[1][2] = sin(angle); northMat[2][1] = -sin(angle); northMat[2][2] = cos(angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 southMat = mat4(1.0); \\r\\n\\tsouthMat[1][1] = cos(-angle); southMat[1][2] = sin(-angle); southMat[2][1] = -sin(-angle); southMat[2][2] = cos(-angle); //rotating about x-axis, based on utime\\r\\n\\tmat4 westMat = mat4(1.0); \\r\\n\\twestMat[0][0] = cos(-angle); westMat[0][1] = sin(-angle); westMat[1][0] = -sin(-angle); westMat[1][1] = cos(-angle); //rotating about z-axis, based on utime\\r\\n\\tmat4 eastMat = mat4(1.0); \\r\\n\\teastMat[0][0] = cos(angle); eastMat[0][1] = sin(angle); eastMat[1][0] = -sin(angle); eastMat[1][1] = cos(angle); //rotating about z-axis, based on utime\\r\\n\\r\\n\\t// vec3 newPos1 = transform(pos + vec3(0, 1.5, 0), cwMat);\\r\\n\\t// vec3 newPos2 = transform(transform(pos + vec3(1.5, 0, 0), ccwMat), eastMat);\\r\\n\\t// vec3 newPos3 = transform(transform(pos + vec3(-1.5, 0, 0), ccwMat), westMat);\\r\\n\\t// vec3 newPos4 = transform(transform(pos + vec3(0, 0, 1.5), ccwMat), northMat);\\r\\n\\t// vec3 newPos5 = transform(transform(pos + vec3(0, 0, -1.5), ccwMat), southMat);\\r\\n\\t// vec3 newPos6 = transform(pos + vec3(2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos7 = transform(pos + vec3(-2, -1.5, -2), cwMat);\\r\\n\\t// vec3 newPos8 = transform(pos + vec3(-2, -1.5, 2), cwMat);\\r\\n\\t// vec3 newPos9 = transform(pos + vec3(2, -1.5, -2), cwMat);\\r\\n\\r\\n\\tif(sceneNumber == 1)\\r\\n\\t{\\r\\n\\t\\t//SCENE 01------------------------------------------------------------\\r\\n\\t\\tfloat dist1;\\r\\n\\t\\t//vec3 newPos1 = transform(transform(pos + vec3(cos((t+4.0)/8.0)*4.0, 0, sin(t/7.0)*3.5), cwMat), northMat);\\r\\n\\t\\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), cwMat), northMat);\\t\\r\\n\\t\\tfloat bb1 = SDF_Sphere(newPos1, 1.1);//boxSDF(newPos1, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb1 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist1 = SDF_Mandlebulb(newPos1, power);\\r\\n\\t\\t}\\t\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist1 = bb1;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist2;\\r\\n\\t\\t//vec3 newPos2 = transform(transform(pos + vec3(cos((t+50.0)/10.0)*2.0, 1, sin((t+30.0)/6.0)*2.5), ccwMat), eastMat);\\r\\n\\t\\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), ccwMat), eastMat);\\t\\r\\n\\t\\tfloat bb2 = SDF_Sphere(newPos2, 1.1);//boxSDF(newPos2, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb2 < .015)\\r\\n\\t\\t{\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist2 = SDF_Mandlebulb(newPos2, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist2 = bb2;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist3;\\r\\n\\t\\t// vec3 newPos3 = transform(transform(pos + vec3(sin((t)/16.0)*3.0, -1, cos((t+75.0)/3.0)*2.0), cwMat), westMat);\\r\\n\\t\\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), cwMat), westMat);\\t\\r\\n\\t\\tfloat bb3 = SDF_Sphere(newPos3, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb3 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist3 = SDF_Mandlebulb(newPos3, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist3 = bb3;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn un(dist1, un(dist2, dist3));\\r\\n\\t}\\r\\n\\telse if(sceneNumber == 2)\\r\\n\\t{\\r\\n\\t\\t//SCENE 02------------------------------------------------------------\\r\\n\\t\\tfloat dist4;\\r\\n\\t\\tmat4 rotateX = mat4(1.0); rotateX[1][1] = 0.0; rotateX[1][2] = 1.0; rotateX[2][1] = -1.0; rotateX[2][2] = 0.0; //rotate 90 degress about x-axis\\r\\n\\t\\tfloat angY = 45.0*3.1415/180.0;\\r\\n\\t\\tmat4 rotateY = mat4(1.0); rotateY[0][0] = cos(angY); rotateY[0][2] = -sin(angY); rotateY[2][0] = sin(angY); rotateY[2][2] = cos(angY); //rotate 45 degrees about y-axis\\r\\n\\t\\tfloat angZ = (2.0*u_time)*3.1415/180.0;\\r\\n\\t\\tmat4 rotateZ = mat4(1.0); rotateZ[0][0] = cos(angZ); rotateZ[0][1] = sin(angZ); rotateZ[1][0] = -sin(angZ); rotateZ[1][1] = cos(angZ); //spin about z-axis\\r\\n\\t\\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \\r\\n\\t\\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), rotateY), rotateZ), rotateX);\\t\\r\\n\\t\\tfloat bb4 = SDF_Sphere(newPos4, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb4 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist4 = SDF_Mandlebulb(newPos4, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist4 = bb4;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist4;\\r\\n\\t}\\r\\n\\telse \\r\\n\\t{\\r\\n\\t\\t//SCENE 03------------------------------------------------------------\\r\\n\\t\\tfloat dist5;\\r\\n\\t\\tmat4 rotateX2 = mat4(1.0); rotateX2[1][1] = 0.0; rotateX2[1][2] = 1.0; rotateX2[2][1] = -1.0; rotateX2[2][2] = 0.0; //rotate 90 degress about x-axis\\r\\n\\t\\tfloat angY2 = -45.0*3.1415/180.0;\\r\\n\\t\\tmat4 rotateY2 = mat4(1.0); rotateY2[0][0] = cos(angY2); rotateY2[0][2] = -sin(angY2); rotateY2[2][0] = sin(angY2); rotateY2[2][2] = cos(angY2); //rotate 45 degrees about y-axis\\r\\n\\t\\tfloat angZ2 = (2.0*u_time)*3.1415/180.0;\\r\\n\\t\\tmat4 rotateZ2 = mat4(1.0); rotateZ2[0][0] = cos(angZ2); rotateZ2[0][2] = -sin(angZ2); rotateZ2[2][0] = sin(angZ2); rotateZ2[2][2] = cos(angZ2); //spin about y-axis\\r\\n\\t\\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), rotateY2), rotateX2), rotateZ2);\\t\\r\\n\\t\\tfloat bb5 = SDF_Sphere(newPos5, 1.1);//boxSDF(newPos3, vec3(1.1,1.1,1.1));\\r\\n\\t\\tif(bb5 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist5 = SDF_Mandlebulb(newPos5, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist5 = bb5;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist5;\\r\\n\\t}\\r\\n\\t\\r\\n\\t// dist1 = SDF_Mandlebulb(newPos1, 12.0);\\r\\n\\t//return dist3;\\r\\n\\t//return un(man1, un(man2, un(man3, un(man4, un(man5, un(man6, un(man7, un(man8, man9))))))));\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\nvec3 computeNormal( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap2(pos + point.xyy) - sceneMap2(pos - point.xyy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yxy) - sceneMap2(pos - point.yxy),\\r\\n\\t\\t\\t\\t\\tsceneMap2(pos + point.yyx) - sceneMap2(pos - point.yyx)));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Check for intersection with the scene for increasing t-values\\r\\nvec2 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\tfloat dist;\\r\\n\\tfloat t = 0.01;\\r\\n\\tfor(int i = 0; i < 500; i++) {\\r\\n\\t\\tfloat dist = sceneMap2(origin + t * direction);\\r\\n\\t\\tif(dist < 0.0001) {\\r\\n\\t\\t\\treturn vec2(t, 1.0); // intersection\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn vec2(0.0, -1.0); // no intersection\\r\\n}\\r\\n\\r\\n\\r\\nfloat SpecHighlight( vec3 toCam, vec3 toLight, vec3 normal) {\\r\\n\\tfloat dot = dot(normalize(toCam + toLight), normal);\\r\\n\\treturn max(dot * dot * dot * dot * dot * dot * dot * dot, 0.0);\\r\\n}\\r\\n\\r\\n// Presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\\r\\nfloat ComputeAO( vec3 pos, vec3 normal ) {\\r\\n\\tfloat tStep = 0.0025;\\r\\n\\tfloat t = 0.0;\\r\\n\\tfloat ao = 1.0;\\r\\n\\tfloat diff = 0.0;\\r\\n\\tfloat k = 72.0;\\r\\n\\tfor(int i = 0; i < 5; i++) {\\r\\n\\t\\tvec3 sample = pos + t * normal;\\r\\n\\t\\tfloat dist = sceneMap2( sample );\\r\\n\\t\\tdiff += pow(0.5, float (i)) * (t - dist);\\r\\n\\t\\tt += tStep;\\r\\n\\t}\\r\\n\\tao -= clamp(k * diff, 0.0, 1.0);\\r\\n\\treturn ao;\\r\\n}\\r\\n\\r\\n\\r\\nvec3 backgroundColor()\\r\\n{\\r\\n\\tint sn = sceneNum();\\r\\n\\tfloat darken; \\r\\n\\tif(sn == 1)\\r\\n\\t{\\r\\n\\t\\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\\r\\n\\t\\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\\r\\n\\t}\\r\\n\\telse if(sn == 2)\\r\\n\\t{\\r\\n\\t\\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\\r\\n\\t\\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\\r\\n\\t}\\r\\n\\t\\r\\n\\tdarken = clamp(darken, 0.2, 1.0);\\r\\n\\r\\n\\tvec3 a = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 b = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 c = vec3(2.0, 1.0, 1.0);\\r\\n\\tvec3 d = vec3(0.5, 0.2, 0.25);\\r\\n\\tfloat t = abs(sin(u_time/12.0));\\r\\n\\tvec3 color = a + b*cos(6.28*(c*t + d));\\r\\n\\r\\n\\treturn darken*color;\\r\\n}\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n\\t\\r\\n\\t/** Raycasting **/\\r\\n\\t\\r\\n\\t// Convering gl_FragCoord to normalized device coordinates: http://www.txutxi.com/?p=182\\r\\n\\tvec2 point_NDC = 2.0 * vec2(gl_FragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t\\t\\t\\tgl_FragCoord.y / u_resolution.y) - 1.0;\\r\\n\\r\\n\\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\\r\\n\\t//vec3 cameraPos = vec3(1, -4, 2);\\r\\n\\t//vec3 cameraPos = vec3(1, 0, 1);\\r\\n\\t\\r\\n\\t// Circle the origin (0, 0, 0)\\r\\n\\t// cameraPos.x = sin(u_time) * 10.0;\\r\\n\\t// cameraPos.z = cos(u_time) * 10.0;\\r\\n\\t\\r\\n\\tfloat len = 10.0; // assume the reference point is at 0, 0, 0\\r\\n\\t\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos);\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = point_NDC.x * H + point_NDC.y * V;\\r\\n\\t\\r\\n\\t// Perform the raymarch\\r\\n\\tvec3 direction = normalize(point_World - cameraPos);\\r\\n\\tvec2 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\t/** Shading and lighting **/\\r\\n\\t\\r\\n\\tif(isect.y > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormal( isectPos );\\r\\n\\t\\t\\r\\n\\t\\t// Lighting\\r\\n\\t\\tvec3 baseMaterial = vec3(0.1, 0.2, 0.2);\\r\\n\\t\\tvec3 trapColor;\\r\\n\\t\\tint sn = sceneNum();\\r\\n\\t\\tif(sn == 1)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(\\r\\n\\t\\t\\t\\tresColor.x-abs(sin((u_time)/2.0+isectPos.z)*0.8), \\r\\n\\t\\t\\t\\tresColor.y-(cos((u_time)/8.0+isectPos.y)*0.5), \\r\\n\\t\\t\\t\\tresColor.z+(cos((u_time)/2.0-isectPos.x)*0.2));\\r\\n\\t\\t}\\r\\n\\t\\telse if(sn == 2)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(resColor) + vec3(0.4);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(0.0, resColor.y+0.4, resColor.z+0.4);\\r\\n\\t\\t}\\r\\n\\t\\tvec3 sun = vec3(0.5, 0.4, 0.3) * 12.0;\\r\\n\\t\\tvec3 sunPos = vec3(5.0, 5.0, 0.0);\\r\\n\\t\\t\\r\\n\\t\\tvec3 toSun = normalize(sunPos - isectPos);\\r\\n\\t\\t\\r\\n\\t\\tnormal = -normal;\\r\\n\\t\\t\\r\\n\\t\\t// Visibility test\\r\\n\\t\\t// vec2 shadowTest = raymarchScene( isectPos, toSun );\\r\\n\\t\\t// float vis = 1.0;\\r\\n\\t\\t\\r\\n\\t\\t// if(shadowTest.y > 0.0) { // something is blocking this point\\r\\n\\t\\t// \\tvis = 0.0;\\r\\n\\t\\t// }\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t\\r\\n\\t\\t// Phong-ish shading for now\\r\\n\\t\\tfloat spec = SpecHighlight( -look, toSun, normal);\\r\\n\\t\\t\\r\\n\\t\\tfloat sunDot = clamp(dot( normal, toSun ), 0.0, 1.0);\\r\\n\\t\\tfloat ao = ComputeAO(isectPos, normal);\\r\\n\\t\\t\\r\\n\\t\\t// Apply lambertian shading - for now\\r\\n\\t\\t\\r\\n\\t\\t//gl_FragColor = ao*vec4(baseMaterial, 1.0);\\r\\n\\t\\tgl_FragColor = /*vis * */ao * vec4(((1.0 - spec) * trapColor * baseMaterial * sun /** vec3(sunDot)*/ + spec * vec3(0.1)), 1);\\r\\n\\t\\t//gl_FragColor = vec4(clamp(normal.x, 0.1, 0.9), -normal.y, normal.z, 1);\\r\\n\\t} else {\\r\\n\\t\\t// Background color\\r\\n\\t\\tgl_FragColor = vec4(backgroundColor(), 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/rayMarch-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 16\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 17\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap 0f1b10213a0dd7f2ee4c","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/firstPass-frag.glsl","webpack:///./src/glsl/secondPass-frag.glsl","webpack:///./src/glsl/thirdPass-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","listener","AudioListener","sound","PositionalAudio","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","audioLoader","AudioLoader","load","buffer","setBuffer","setLoop","setVolume","play","aspect","updateProjectionMatrix","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","target1","WebGLRenderTarget","composer1","shaderPass1","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","u_cwMat","u_ccwMat","u_northMat","u_southMat","u_westMat","u_eastMat","u_rotateX1","u_rotateY1","u_rotateZ1","u_rotateX2","u_rotateY2","u_rotateZ2","vertexShader","fragmentShader","composer2","shaderPass2","u_firstPass","u_previousFrame","renderToScreen","material","writeBuffer","texture","target3","composer3","shaderPass3","u_input","addPass","getElapsedTime","angle","cwMat","Matrix4","makeRotationY","ccwMat","northMat","makeRotationX","southMat","eastMat","makeRotationZ","westMat","rotateX1","rotateY1","rotateZ1","rotateX2","rotateY2","rotateZ2"],"mappings":"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AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,SAAQ,OAAO;AACf;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA,qEAAoE,iCAAiC;;AAErG;;AAEA;AACA;;;;AAIA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA,WAAU,iDAAiD,gBAAgB,uBAAuB,2BAA2B,qBAAqB,qBAAqB,GAAG,gBAAgB,yBAAyB,2BAA2B,gBAAgB,wBAAwB,yBAAyB,+BAA+B,GAAG,sBAAsB,0BAA0B,uBAAuB,2BAA2B,4BAA4B,gBAAgB,iBAAiB,uBAAuB,qBAAqB,kBAAkB,iBAAiB,GAAG;;;AAGlkB;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;;AAEA;AACA;AACA,4C;AACA,YAAW;AACX;AACA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AA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AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA,sBAAqB,mGAAmG,aAAa,2CAA2C,mBAAmB,SAAS,KAAK,4BAA4B,YAAY,gBAAgB,oCAAoC,WAAW,qCAAqC,gBAAgB,uBAAuB,iBAAiB,oCAAoC,eAAe,4BAA4B,uCAAuC,cAAc,iBAAiB;AAC1iB,mBAAkB,iBAAiB,oCAAoC,gBAAgB,mCAAmC,WAAW,YAAY,uBAAuB,qBAAqB,qBAAqB,EAAE,qCAAqC,2BAA2B,YAAY,WAAW,uBAAuB,iBAAiB,oCAAoC,UAAU,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EA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,sBAAsB;;AAE5D;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4BAA2B;;;AAG3B;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAE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AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kBAAiB,eAAe,eAAe;AAC/C,kBAAiB,eAAe,eAAe;AAC/C,kBAAiB,eAAe,gBAAgB;AAChD,kBAAiB,eAAe,gBAAgB;;AAEhD;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;;AAGA,mBAAkB,eAAe;AACjC,mBAAkB,eAAe;AACjC,mBAAkB,eAAe;;AAEjC;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,qBAAoB,kBAAkB,kBAAkB;AACxD,qBAAoB,kBAAkB,kBAAkB;AACxD,sBAAqB,mBAAmB,oBAAoB;AAC5D,uBAAsB,oBAAoB,oBAAoB;;AAE9D;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,cAAc,cAAc;AAC5C,iBAAgB,cAAc,cAAc;AAC5C,iBAAgB,cAAc,eAAe;AAC7C,iBAAgB,cAAc,eAAe;;AAE7C;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,kBAAiB,mBAAmB;AACpC,kBAAiB,mBAAmB;AACpC,kBAAiB,mBAAmB;;AAEpC,kBAAiB,oBAAoB;AACrC,kBAAiB,oBAAoB;AACrC,mBAAkB,qBAAqB;;AAEvC;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;;AAE9B;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,0CAAyC;;AAEzC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,gBAAe,aAAa,aAAa;AACzC,gBAAe,aAAa,aAAa;AACzC,gBAAe,aAAa,cAAc;AAC1C,gBAAe,aAAa,gBAAgB;;AAE5C;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,oBAAmB,aAAa,aAAa;AAC7C,gBAAe,iBAAiB,aAAa;AAC7C,gBAAe,aAAa,oBAAoB;AAChD,gBAAe,aAAa,cAAc;;AAE1C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,oBAAmB,QAAQ;;AAE3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,QAAQ;;AAE1B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,gCAA+B,eAAe;;AAE9C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mBAAkB,SAAS;AAC3B;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gCAA+B,8BAA8B;AAC7D,gCAA+B,8BAA8B;;AAE7D;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,iCAAgC,+BAA+B;AAC/D,iCAAgC,+BAA+B;AAC/D,iCAAgC,+BAA+B;;AAE/D;;AAEA;;AAEA;;AAEA,mCAAkC;AAClC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC,mCAAkC;AAClC,mCAAkC;;AAElC,gDAA+C;AAC/C,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA,iCAAgC,+BAA+B;AAC/D,iCAAgC,+BAA+B;;AAE/D;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mBAAkB,SAAS;;AAE3B;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mBAAkB,SAAS;;AAE3B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC,oCAAmC;AACnC,oCAAmC;AACnC,oCAAmC;;AAEnC,oCAAmC;AACnC,oCAAmC;;AAEnC,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,kCAAiC;;AAEjC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,kCAAiC;;AAEjC;;AAEA;;AAEA;;AAEA,iCAAgC;;AAEhC;;AAEA;;AAEA;AACA;;AAEA;;AAEA,mCAAkC,SAAS;;AAE3C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,SAAQ,EAAE;;AAEV;AACA;;AAEA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA,mCAAkC,SAAS;;AAE3C;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,mCAAkC,SAAS;;AAE3C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,oBAAmB,qBAAqB;;AAExC;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,iGAAgG;;AAEhG,kFAAiF;;AAEjF,0FAAyF;;AAEzF,iIAAgI,uDAAuD,6HAA6H,yHAAyH;;AAE7a,yEAAwE,iCAAiC;;AAEzG,4DAA2D;;AAE3D,iEAAgE;;AAEhE,4JAA2J,iCAAiC,kIAAkI,yGAAyG,yDAAyD,8FAA8F,eAAe,iBAAiB,GAAG,2DAA2D,wCAAwC,GAAG,uEAAuE,mEAAmE,6DAA6D,GAAG,yFAAyF,6BAA6B,iEAAiE,iEAAiE,6BAA6B,GAAG,mGAAmG,6BAA6B,iEAAiE,iEAAiE,yCAAyC,GAAG,6DAA6D,6BAA6B,qDAAqD,8CAA8C,GAAG,6JAA6J,oCAAoC,2EAA2E,8EAA8E,uEAAuE,8DAA8D,sEAAsE,+CAA+C,2DAA2D,oCAAoC,yBAAyB,GAAG,yFAAyF,iCAAiC,sDAAsD,yCAAyC,6BAA6B,8BAA8B,+BAA+B,sCAAsC,gGAAgG,mCAAmC,cAAc,GAAG,wDAAwD,mBAAmB,oCAAoC,oCAAoC,oCAAoC,oCAAoC,UAAU,wBAAwB,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,mBAAmB,KAAK,0BAA0B,YAAY,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,KAAK,2BAA2B,YAAY,kBAAkB,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,kBAAkB,kBAAkB,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,4CAA4C,4CAA4C,KAAK,2BAA2B,YAAY,KAAK,mCAAmC,mCAAmC,GAAG,0DAA0D,mCAAmC,mCAAmC,uFAAuF,eAAe,GAAG,uHAAuH,iDAAiD,iDAAiD,iDAAiD,iDAAiD,GAAG,2HAA2H,6BAA6B,8BAA8B,+BAA+B,gBAAgB,wCAAwC,0BAA0B,mEAAmE,wBAAwB,4DAA4D,4DAA4D,4DAA4D,4DAA4D,UAAU,sCAAsC,8CAA8C,iDAAiD,iDAAiD,iDAAiD,iDAAiD,iDAAiD,oBAAoB,0EAA0E,0EAA0E,0EAA0E,2FAA2F,2FAA2F,0BAA0B,sCAAsC,gBAAgB,GAAG,4QAA4Q,uBAAuB,4EAA4E,sDAAsD,gCAAgC,kDAAkD,gCAAgC,oDAAoD,0HAA0H,kGAAkG,yCAAyC,+BAA+B,GAAG,iLAAiL,uBAAuB,4EAA4E,kCAAkC,+FAA+F,8BAA8B,GAAG,mIAAmI,uEAAuE,0DAA0D,oDAAoD,iCAAiC,sEAAsE,gDAAgD,uCAAuC,GAAG,kCAAkC,gBAAgB,GAAG,wEAAwE,+EAA+E,GAAG,oKAAoK,2EAA2E,8DAA8D,sEAAsE,+CAA+C,uCAAuC,+CAA+C,yBAAyB,GAAG,oEAAoE,yDAAyD,GAAG,qEAAqE,iDAAiD,GAAG;;AAEtnT,+EAA8E,4BAA4B,sBAAsB,+BAA+B,+BAA+B,0DAA0D,wEAAwE,wEAAwE,8BAA8B,KAAK,wEAAwE,sCAAsC,sCAAsC,0BAA0B,qCAAqC,qCAAqC,sCAAsC,kEAAkE,0DAA0D,KAAK;;AAE10B,iFAAgF,2BAA2B,SAAS,uCAAuC,+DAA+D,KAAK,mFAAmF,0CAA0C,yBAAyB,SAAS,yCAAyC,2EAA2E,OAAO,6BAA6B;;AAEthB,sJAAqJ,iEAAiE;;AAEtN,8IAA6I;;AAE7I,+IAA8I;;AAE9I,uEAAsE;;AAEtE,qEAAoE;;AAEpE,mEAAkE;;AAElE,iEAAgE;;AAEhE,yVAAwV,YAAY,EAAE,kCAAkC,cAAc,EAAE,kCAAkC,gBAAgB,cAAc,EAAE,wCAAwC,qCAAqC,EAAE,wCAAwC,8DAA8D,mEAAmE,8BAA8B,GAAG,wBAAwB,eAAe,mBAAmB,iBAAiB,IAAI,yBAAyB,uBAAuB,wBAAwB,yBAAyB,0BAA0B,IAAI,2BAA2B,kBAAkB,gBAAgB,iBAAiB,IAAI,0DAA0D,0DAA0D,GAAG,iEAAiE,0DAA0D,GAAG,kFAAkF,8DAA8D,4CAA4C,GAAG,iFAAiF,4DAA4D,GAAG,oHAAoH,gIAAgI,GAAG,qCAAqC,aAAa,0CAA0C,0CAA0C,0CAA0C,eAAe,GAAG;;AAEhhE,gJAA+I,uCAAuC,kBAAkB,2CAA2C,mFAAmF,mDAAmD,KAAK,UAAU,mFAAmF,mDAAmD,KAAK,gBAAgB,GAAG,6LAA6L,yDAAyD,wCAAwC,wCAAwC,gDAAgD,gDAAgD,kDAAkD,yCAAyC,mCAAmC,kDAAkD,GAAG,iMAAiM,uEAAuE,2CAA2C,gEAAgE,qDAAqD,mDAAmD,+DAA+D,yEAAyE,gCAAgC,6CAA6C,WAAW,gBAAgB,+CAA+C,uCAAuC,oBAAoB,uDAAuD,sDAAsD,2DAA2D,KAAK,yBAAyB,sDAAsD,yDAAyD,2DAA2D,KAAK,yBAAyB,sDAAsD,6DAA6D,2DAA2D,KAAK,yBAAyB,sDAAsD,qDAAqD,6DAA6D,KAAK,yBAAyB,uDAAuD,wDAAwD,6DAA6D,KAAK,UAAU,uDAAuD,4DAA4D,6DAA6D,KAAK,qBAAqB,oDAAoD,uDAAuD,6CAA6C,oDAAoD,GAAG,gIAAgI,oDAAoD,mCAAmC,wBAAwB,kCAAkC,mEAAmE,wBAAwB,6BAA6B,gCAAgC,yCAAyC,2CAA2C,2DAA2D,iEAAiE,2DAA2D,iEAAiE,2CAA2C,iCAAiC,GAAG;;AAE5mI,gFAA+E,+DAA+D;;AAE9I,qGAAoG,oCAAoC,mCAAmC;;AAE3K,oKAAmK;;AAEnK,2GAA0G,sEAAsE,+CAA+C;;AAE/N,2FAA0F;;AAE1F,iFAAgF;;AAEhF,yEAAwE,iBAAiB,GAAG,6DAA6D,kEAAkE,GAAG,6DAA6D,wEAAwE,GAAG,sCAAsC,sLAAsL,GAAG,sCAAsC,uKAAuK,GAAG,sCAAsC,oEAAoE,GAAG,sCAAsC,iEAAiE,sEAAsE,sEAAsE,GAAG,yDAAyD,uDAAuD,GAAG,yDAAyD,2DAA2D,wDAAwD,6CAA6C,mDAAmD,GAAG,yDAAyD,uEAAuE,GAAG,yDAAyD,2DAA2D,iDAAiD,kDAAkD,+DAA+D,GAAG,uGAAuG,yCAAyC,0CAA0C,uDAAuD,iBAAiB,4CAA4C,+CAA+C,0BAA0B,4DAA4D,mBAAmB,GAAG,mHAAmH,wCAAwC,yCAAyC,mBAAmB,2CAA2C,wCAAwC,wCAAwC,gDAAgD,uCAAuC,GAAG;;AAE3wF,iMAAgM,yEAAyE,oGAAoG,6FAA6F,sDAAsD,gJAAgJ,4DAA4D,qEAAqE,uGAAuG,oDAAoD,+JAA+J,sEAAsE,2CAA2C,yDAAyD,6IAA6I,kIAAkI,8GAA8G;;AAElnD,6GAA4G,kCAAkC,wKAAwK,sEAAsE,wCAAwC,uCAAuC,yIAAyI,qCAAqC;;AAEznB,6JAA4J,qCAAqC,oCAAoC;;AAErO,+JAA8J,qFAAqF,oFAAoF,6FAA6F,sFAAsF;;AAE1f,+DAA8D;;AAE9D,kEAAiE;;AAEjE,iKAAgK,yEAAyE,8EAA8E;;AAEvT,mEAAkE,2BAA2B,kDAAkD,qCAAqC,2BAA2B;;AAE/M,gFAA+E,oEAAoE,kDAAkD,kDAAkD,+EAA+E,wEAAwE,iBAAiB;;AAE/Z,6IAA4I;;AAE5I,kFAAiF,oCAAoC;;AAErH,0DAAyD,4BAA4B,qCAAqC,mDAAmD,kDAAkD,gCAAgC,4CAA4C,yCAAyC,0CAA0C,4BAA4B,kDAAkD,oCAAoC,cAAc,gCAAgC,8CAA8C,sBAAsB,SAAS,+EAA+E,4DAA4D,wDAAwD,kEAAkE,6FAA6F,iBAAiB,qDAAqD,qBAAqB,SAAS,6EAA6E,4DAA4D,wDAAwD,kEAAkE,6FAA6F,iBAAiB,oDAAoD,oBAAoB,SAAS,2FAA2F,4DAA4D,wDAAwD,kEAAkE,6FAA6F,iBAAiB,qDAAqD,qBAAqB,SAAS,qFAAqF,mHAAmH,iBAAiB;;AAE9pE,oDAAmD,qEAAqE,wCAAwC,4DAA4D,gCAAgC,GAAG,qDAAqD,qBAAqB,iBAAiB,iBAAiB,uBAAuB,yBAAyB,yBAAyB,MAAM,iEAAiE,+JAA+J,iDAAiD,yDAAyD,iCAAiC,KAAK,yDAAyD,oBAAoB,iBAAiB,qBAAqB,kBAAkB,iBAAiB,uBAAuB,yBAAyB,yBAAyB,MAAM,uDAAuD,6IAA6I,6DAA6D,mDAAmD,8CAA8C,2CAA2C,4HAA4H,iEAAiE,KAAK,uDAAuD,oBAAoB,qBAAqB,iBAAiB,qBAAqB,kBAAkB,oBAAoB,wBAAwB,iBAAiB,uBAAuB,yBAAyB,yBAAyB,MAAM,oDAAoD,2IAA2I,4DAA4D,mDAAmD,8CAA8C,yEAAyE,2CAA2C,4FAA4F,4CAA4C,yIAAyI,mCAAmC,OAAO,OAAO,wCAAwC,oCAAoC,OAAO,KAAK,gEAAgE,iBAAiB,oBAAoB,qBAAqB,sBAAsB,MAAM,6BAA6B,2BAA2B,iEAAiE,6DAA6D,qBAAqB,oBAAoB,uBAAuB,MAAM,gEAAgE,iHAAiH,gEAAgE,kDAAkD,4FAA4F,gEAAgE,oCAAoC,KAAK,oKAAoK,kFAAkF,wGAAwG,uHAAuH,gGAAgG,+EAA+E,qHAAqH,0DAA0D,kDAAkD,gEAAgE,KAAK,kGAAkG,qDAAqD,+GAA+G,8DAA8D,KAAK,+IAA+I,2GAA2G,oGAAoG,mFAAmF,0FAA0F,6GAA6G,0HAA0H,mGAAmG,+EAA+E,0HAA0H,+GAA+G,gEAAgE,0DAA0D,+EAA+E,iHAAiH,0FAA0F,+EAA+E,oJAAoJ,mIAAmI,4GAA4G,+EAA+E,2DAA2D,KAAK;;AAE39N,2DAA0D,2CAA2C,oCAAoC,yCAAyC,+CAA+C;;AAEjO,+DAA8D,8CAA8C,qCAAqC,uBAAuB,wBAAwB,6BAA6B,4BAA4B,IAAI,6NAA6N,gDAAgD,iDAAiD,8CAA8C,kFAAkF,6MAA6M,+JAA+J,8EAA8E,8EAA8E,KAAK,0LAA0L,2HAA2H,uFAAuF,kDAAkD,sEAAsE,yGAAyG,oLAAoL,GAAG,iLAAiL,iGAAiG,GAAG;;AAEjwE,4DAA2D,uEAAuE,mEAAmE,6HAA6H,0IAA0I,+CAA+C,uEAAuE;;AAElkB,gEAA+D,uBAAuB,6BAA6B,wBAAwB,0CAA0C,+BAA+B,cAAc,oKAAoK,6IAA6I,GAAG,yNAAyN,gDAAgD,iDAAiD,8CAA8C,mDAAmD,6MAA6M,+JAA+J,wEAAwE,wEAAwE,KAAK,sLAAsL,4EAA4E,gDAAgD,4DAA4D,uIAAuI,wCAAwC,oLAAoL,wHAAwH,2MAA2M,aAAa,6KAA6K,iGAAiG,GAAG,6MAA6M,6FAA6F,0BAA0B,yGAAyG,wCAAwC,mLAAmL,mNAAmN,aAAa,kkBAAkkB,kHAAkH,GAAG;;AAEnwI,qDAAoD,sCAAsC,2BAA2B,gDAAgD,4BAA4B,gFAAgF,oBAAoB,sBAAsB,SAAS,oCAAoC,yEAAyE,4PAA4P,+EAA+E,KAAK,qFAAqF,oBAAoB,qBAAqB,SAAS,kCAAkC,uEAAuE,iPAAiP,+EAA+E,KAAK,kGAAkG,oBAAoB,oBAAoB,SAAS,gDAAgD,qFAAqF,2RAA2R,+EAA+E,KAAK,2GAA2G,oBAAoB,0BAA0B,SAAS,0CAA0C,8EAA8E,KAAK,gHAAgH,2GAA2G,wEAAwE,mDAAmD,+DAA+D,qBAAqB,SAAS,sFAAsF,OAAO,mKAAmK,mFAAmF,mLAAmL,uJAAuJ,oDAAoD,qGAAqG;;AAEr8G,uJAAsJ;;AAEtJ,yFAAwF,6DAA6D;;AAErJ,oHAAmH,0CAA0C;;AAE7J,gIAA+H,qEAAqE,qEAAqE;;AAEzQ,gFAA+E,gDAAgD,+BAA+B;;AAE9J,mEAAkE;;AAElE,sKAAqK,iDAAiD;;AAEtN,gFAA+E,0BAA0B;;AAEzG,iEAAgE,kFAAkF,wCAAwC;;AAE1L,8FAA6F;;AAE7F,8HAA6H,2EAA2E,2EAA2E,2EAA2E;;AAE9V,iIAAgI,sDAAsD;;AAEtL,+HAA8H,4EAA4E,4EAA4E,4EAA4E,wGAAwG,4EAA4E,4EAA4E,4EAA4E;;AAE9qB,uGAAsG,kCAAkC;;AAExI,4IAA2I,iGAAiG,iDAAiD,2DAA2D,uFAAuF,mGAAmG;;AAElhB,qFAAoF,6BAA6B,4DAA4D,oCAAoC,oCAAoC,gCAAgC,gCAAgC,oDAAoD,qDAAqD,sCAAsC,8DAA8D,sCAAsC,iCAAiC,qCAAqC,KAAK;;AAEnnB,+DAA8D,2CAA2C,GAAG,+CAA+C,+BAA+B,GAAG,wCAAwC,0CAA0C,0EAA0E,uEAAuE,sCAAsC,4CAA4C,iDAAiD,iCAAiC,yBAAyB,GAAG,8CAA8C,mCAAmC,GAAG,mGAAmG,6CAA6C,GAAG,yGAAyG,+CAA+C,GAAG,kGAAkG,iEAAiE,GAAG,qGAAqG,gEAAgE,GAAG;;AAEhzC,uGAAsG;;AAEtG,2FAA0F,wEAAwE,sDAAsD;;AAExN,iEAAgE,kFAAkF,wCAAwC;;AAE1L,8FAA6F;;AAE7F,8IAA6I,6DAA6D,8FAA8F,uDAAuD,iGAAiG,yDAAyD,kFAAkF,2EAA2E,KAAK,sFAAsF,2CAA2C,0CAA0C,wDAAwD,yFAAyF,yFAAyF,yFAAyF,yFAAyF,wCAAwC,mCAAmC,mCAAmC,iCAAiC,eAAe,KAAK,wHAAwH,uCAAuC,kCAAkC,4HAA4H,2CAA2C,sEAAsE,+CAA+C,0BAA0B,4FAA4F,iDAAiD,iDAAiD,iDAAiD,iDAAiD,w0BAAw0B,mGAAmG,iDAAiD,iDAAiD,iDAAiD,iDAAiD,0+BAA0+B,uFAAuF,mBAAmB,iBAAiB,KAAK,+CAA+C,2BAA2B,qEAAqE,0BAA0B,oDAAoD,yBAAyB,4CAA4C,2CAA2C,kCAAkC,uDAAuD,OAAO,kCAAkC,kCAAkC,6CAA6C,OAAO,kCAAkC,kCAAkC,2CAA2C,qCAAqC,OAAO,gEAAgE,KAAK,6HAA6H,0EAA0E,6CAA6C,+CAA+C,qEAAqE,+IAA+I,4zBAA4zB,2FAA2F,iBAAiB;;AAEzhN,0IAAyI,6DAA6D,4FAA4F,uDAAuD,+FAA+F,yDAAyD;;AAEjf,4FAA2F,oBAAoB,SAAS,kFAAkF,KAAK,yDAAyD,qBAAqB,SAAS,oEAAoE,KAAK,0DAA0D,sBAAsB,SAAS,sEAAsE,KAAK;;AAEnhB,yDAAwD,uBAAuB,wFAAwF,oBAAoB,oBAAoB,SAAS,gDAAgD,yNAAyN,KAAK,6DAA6D,oBAAoB,qBAAqB,SAAS,kCAAkC,+KAA+K,KAAK,gEAAgE,oBAAoB,sBAAsB,SAAS,oCAAoC,0LAA0L,KAAK,sCAAsC,GAAG;;AAE1qC,6FAA4F,iDAAiD,iDAAiD,iDAAiD;;AAE/O,6EAA4E,mCAAmC,2DAA2D,mCAAmC,oCAAoC,8CAA8C,0BAA0B,sDAAsD,yDAAyD,mDAAmD,oDAAoD,6BAA6B,wEAAwE,wEAAwE,wEAAwE,wEAAwE,2CAA2C,oBAAoB,OAAO,sDAAsD,8CAA8C,2CAA2C,oBAAoB,OAAO;;AAE5jC,wGAAuG,+BAA+B,oDAAoD,oDAAoD,oDAAoD,oDAAoD,2CAA2C;;AAEjY,gFAA+E,0CAA0C,0CAA0C,0CAA0C,0CAA0C,8DAA8D,sEAAsE;;AAE3X,qDAAoD,+EAA+E,uCAAuC,kCAAkC;;AAE5M,2FAA0F;;AAE1F,gHAA+G;;AAE/G,+GAA8G,sCAAsC,wCAAwC,uCAAuC,GAAG,0CAA0C,iCAAiC,uDAAuD,GAAG,8MAA8M,iCAAiC,qGAAqG,GAAG,iDAAiD,iCAAiC,8CAA8C,4GAA4G,GAAG;;AAEj7B,gRAA+Q;;AAE/Q,8QAA6Q,8BAA8B;;AAE3S,qSAAoS;;AAEpS,oGAAmG;;AAEnG,mGAAkG,sBAAsB;;AAExH,sFAAqF;;AAErF,wNAAuN,2EAA2E;;AAElS,6CAA4C,sBAAsB,wBAAwB,8BAA8B,kCAAkC,6FAA6F,8BAA8B,GAAG;;AAExR,+CAA8C,kCAAkC,iEAAiE,2DAA2D;;AAE5M,uEAAsE,4OAA4O,2EAA2E,4DAA4D,mOAAmO,sFAAsF,aAAa;;AAE/vB,wQAAuQ,2RAA2R;;AAEliB,iDAAgD,8BAA8B,iGAAiG,kIAAkI,GAAG;;AAEpT,uDAAsD,+IAA+I,2PAA2P,GAAG;;AAEnc,mDAAkD,sBAAsB,8BAA8B,kCAAkC,iDAAiD,kBAAkB,8DAA8D,yEAAyE,oDAAoD,GAAG;;AAEzY,mDAAkD,kCAAkC,iEAAiE,2DAA2D;;AAEhN,8CAA6C,wBAAwB,yBAAyB,0BAA0B,8BAA8B,gLAAgL,8FAA8F,cAAc,KAAK,qCAAqC,iDAAiD,qGAAqG,yDAAyD,6IAA6I;;AAExzB,6CAA4C,+BAA+B,8BAA8B,wKAAwK,oEAAoE,8DAA8D,gDAAgD,kGAAkG;;AAEriB,6CAA4C,wBAAwB,8CAA8C,8bAA8b,wFAAwF,wSAAwS,mHAAmH,6DAA6D,8FAA8F,wDAAwD,iHAAiH,6IAA6I;;AAEp/C,yVAAwV,iiBAAiiB;;AAEz3B,+CAA8C,wBAAwB,wBAAwB,2BAA2B,iDAAiD,2mBAA2mB,wFAAwF,yGAAyG,0CAA0C,sTAAsT,+GAA+G,0GAA0G,0DAA0D,yGAAyG,4IAA4I,iHAAiH,6IAA6I;;AAE5jE,oEAAmE,iDAAiD,uZAAuZ,qkBAAqkB;;AAEhlC,4DAA2D,wBAAwB,wBAAwB,0BAA0B,wBAAwB,itBAAitB,wFAAwF,yGAAyG,0CAA0C,0iBAA0iB,uFAAuF,6IAA6I;;AAEv2D,kEAAiE,8CAA8C,qZAAqZ,iTAAiT,+QAA+Q,qHAAqH;;AAEzrC,kEAAiE,wBAAwB,0BAA0B,0BAA0B,wBAAwB,8CAA8C,qCAAqC,qCAAqC,8CAA8C,swBAAswB,wFAAwF,yGAAyG,0CAA0C,qnBAAqnB,yDAAyD,6IAA6I;;AAEvnE,wEAAuE,8CAA8C,4ZAA4Z,iTAAiT,+QAA+Q,yFAAyF;;AAE1qC,2DAA0D,iHAAiH,sDAAsD,oLAAoL,yJAAyJ,GAAG;;AAEjjB,oJAAmJ,sDAAsD,mMAAmM,6PAA6P,4TAA4T,WAAW;;AAEh9B,0CAAyC,wBAAwB,+QAA+Q,4EAA4E,iDAAiD,0KAA0K,yDAAyD,6IAA6I;;AAE7zB,wCAAuC,sBAAsB,0MAA0M,wKAAwK,mCAAmC,yKAAyK;;AAE3nB,2CAA0C,yKAAyK,8EAA8E,GAAG;;AAEpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iCAAgC;;AAEhC;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,0DAAyD;AACzD,0CAAyC;AACzC,0CAAyC;;AAEzC;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,eAAc,YAAY;;AAE1B;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,uBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,iBAAgB;;AAEhB;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,cAAa,+BAA+B;AAC5C,cAAa,aAAa;;AAE1B,UAAS,cAAc;AACvB,mBAAkB,mCAAmC;;AAErD,kBAAiB,cAAc;AAC/B,eAAc,cAAc;;AAE5B,aAAY,cAAc;AAC1B,iBAAgB,aAAa;AAC7B,mBAAkB,aAAa;AAC/B,sBAAqB;;AAErB,IAAG;;AAEH;;AAEA,YAAW,cAAc;AACzB,qBAAoB;;AAEpB,IAAG;;AAEH;;AAEA,eAAc,cAAc;AAC5B,wBAAuB;;AAEvB,IAAG;;AAEH;;AAEA,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,cAAa,cAAc;AAC3B,gBAAe;;AAEf,IAAG;;AAEH;;AAEA,gBAAe,cAAc;AAC7B,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,sBAAqB,cAAc;AACnC,wBAAuB,WAAW;AAClC,uBAAsB;;AAEtB,IAAG;;AAEH;;AAEA,mBAAkB;;AAElB,IAAG;;AAEH;;AAEA,mBAAkB;;AAElB,IAAG;;AAEH;;AAEA,kBAAiB;;AAEjB,IAAG;;AAEH;;AAEA,iBAAgB,iBAAiB;AACjC,cAAa,WAAW;AACxB,aAAY,cAAc;AAC1B,eAAc;;AAEd,IAAG;;AAEH;;AAEA,wBAAuB,YAAY;;AAEnC,wBAAuB;AACvB,kBAAiB;AACjB,cAAa;;AAEb,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,2BAA0B,YAAY;AACtC,8BAA6B,YAAY;;AAEzC,iBAAgB;AAChB,cAAa;AACb,iBAAgB;AAChB,kBAAiB;AACjB,iBAAgB;AAChB,gBAAe;AACf,oBAAmB;AACnB,cAAa;;AAEb,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,oBAAmB,YAAY;AAC/B,uBAAsB,YAAY;;AAElC,kBAAiB;AACjB,cAAa;AACb,iBAAgB;AAChB,cAAa;AACb,iBAAgB;;AAEhB,eAAc;AACd,mBAAkB;AAClB,qBAAoB;AACpB;AACA,KAAI,EAAE;;AAEN,qBAAoB,YAAY;AAChC,wBAAuB,YAAY;;AAEnC,uBAAsB;AACtB,kBAAiB;AACjB,iBAAgB;AAChB;AACA,KAAI,EAAE;;AAEN;AACA,qBAAoB;AACpB,cAAa;AACb,iBAAgB;AAChB,cAAa;AACb;AACA,KAAI;;AAEJ,IAAG;;AAEH;;AAEA,cAAa,+BAA+B;AAC5C,cAAa,aAAa;AAC1B,WAAU,aAAa;AACvB,YAAW,aAAa;AACxB,UAAS,cAAc;AACvB,mBAAkB;;AAElB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB;AAChB;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB,+BAA+B;AAC/C,iBAAgB,+BAA+B;AAC/C,kBAAiB;AACjB;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAgB,+BAA+B;AAC/C,kBAAiB,aAAa;AAC9B,kBAAiB,WAAW;AAC5B,wBAAuB,WAAW;AAClC;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA,cAAa,WAAW;AACxB,iBAAgB,WAAW;AAC3B,kBAAiB;AACjB;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;;AAEA;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA,aAAY,cAAc;AAC1B,aAAY,aAAa;AACzB,eAAc;AACd,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;AACA;AACA;;AAEA;;AAEA;AACA,iBAAgB,cAAc;AAC9B,aAAY;AACZ,KAAI;;AAEJ;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA,gBAAe;AACf,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,iBAAgB,WAAW;AAC3B,0BAAyB;AACzB;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mCAAkC;;AAElC,mCAAkC;AAClC,0BAAyB;AACzB,8BAA6B;;AAE7B,sCAAqC;;AAErC,+BAA8B;AAC9B,yBAAwB;;AAExB,wBAAuB;AACvB,iCAAgC;;AAEhC,oBAAmB;;AAEnB,iBAAgB;;AAEhB,4BAA2B;;AAE3B,gCAA+B;;AAE/B,uEAAsE;AACtE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;AAClE,mEAAkE;;AAElE,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;AAChD,iDAAgD;;AAEhD,6EAA4E;AAC5E,6EAA4E;;AAE5E,SAAQ;;AAER,4FAA2F;;AAE3F,QAAO;;AAEP;;AAEA;;AAEA,mCAAkC;;AAElC,6BAA4B;AAC5B,6BAA4B;AAC5B,0BAAyB;;AAEzB,wBAAuB;AACvB,iCAAgC;;AAEhC,oBAAmB;;AAEnB;;AAEA,gCAA+B;;AAE/B,mDAAkD;;AAElD;;AAEA,SAAQ,8BAA8B;;AAEtC,8CAA6C;;AAE7C;;AAEA,SAAQ,OAAO;;AAEf,8CAA6C;AAC7C,4CAA2C;AAC3C,gCAA+B;AAC/B,mCAAkC;;AAElC,SAAQ;;AAER,QAAO;;AAEP;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,uCAAsC,OAAO;;AAE7C;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;;AAGA;;AAEA;AACA;AACA;;;AAGA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA;;AAEA;AACA;;AAEA,oDAAmD,QAAQ;;AAE3D;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,kEAAiE;;AAEjE;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;;AAGA;;AAEA,wCAAuC,OAAO;;AAE9C;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,wCAAuC,OAAO;;AAE9C;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,sDAAqD;;AAErD,mCAAkC;AAClC,oCAAmC;AACnC,6BAA4B;AAC5B,yBAAwB;AACxB,4BAA2B;AAC3B,2BAA0B;;AAE1B,8BAA6B;AAC7B,wBAAuB;;AAEvB,uBAAsB;;AAEtB,mBAAkB;;AAElB,qCAAoC;;AAEpC,+CAA8C;;AAE9C,4BAA2B;AAC3B,qGAAoG;AACpG,qGAAoG;;AAEpG,0BAAyB;;AAEzB,oEAAmE;AACnE,2CAA0C;AAC1C,wDAAuD;;AAEvD,mCAAkC;;AAElC,OAAM;;AAEN;;AAEA;;AAEA,sDAAqD;;AAErD,yBAAwB;AACxB,4BAA2B;AAC3B,4BAA2B;;AAE3B,0BAAyB;AACzB,4BAA2B;AAC3B,+BAA8B;AAC9B,4BAA2B;AAC3B,2BAA0B;AAC1B,8BAA6B;;AAE7B,uBAAsB;;AAEtB,mBAAkB;;AAElB,4CAA2C;;AAE3C,4CAA2C;;AAE3C,uEAAsE;;AAEtE,2BAA0B;;AAE1B,sDAAqD;AACrD,8BAA6B;;AAE7B,6BAA4B;;AAE5B,0DAAyD;;AAEzD,SAAQ,OAAO;;AAEf,qCAAoC;AACpC,8EAA6E;AAC7E,wDAAuD;;AAEvD,SAAQ;;AAER,wFAAuF;;AAEvF,QAAO;;AAEP,OAAM;;AAEN;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,uBAAuB;;AAE7D;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gCAA+B;AAC/B,gCAA+B;;AAE/B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,yBAAwB;;AAExB;AACA;AACA;;AAEA;AACA;;AAEA,qBAAoB;;AAEpB;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA,kBAAiB;AACjB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,2CAA0C;;AAE1C;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA,qBAAoB,SAAS;AAC7B;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,iBAAiB;;AAEzC,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,oBAAoB;AACnC,iBAAgB,gBAAgB,aAAa,iBAAiB,YAAY,EAAE;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,qCAAoC,6EAA6E,GAAG;AACpH,uCAAsC,8CAA8C,GAAG;;AAEvF;;AAEA;AACA;;AAEA,oBAAmB;AACnB,uBAAsB;AACtB,yBAAwB;;AAExB,yBAAwB;AACxB,6BAA4B;AAC5B,6BAA4B;;AAE5B;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,sCAAqC,OAAO;;AAE5C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,yCAAwC,OAAO;;AAE/C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,wCAAuC,QAAQ;;AAE/C;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,yCAAwC,OAAO;;AAE/C;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;AACjF,kFAAiF;;AAEjF;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,+CAA8C;;AAE9C;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,yCAAwC,QAAQ;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,kBAAiB,eAAe;AAChC,kBAAiB,eAAe;AAChC,kBAAiB,eAAe;;AAEhC;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;AAC9B,iBAAgB,cAAc;;AAE9B;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,iBAAgB,iBAAiB;AACjC,iBAAgB,iBAAiB;AACjC,iBAAgB,iBAAiB;;AAEjC;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;A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AEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;A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AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA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A;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;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;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,sBAAqB,eAAe;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;AAEA,wCAAuC,SAAS;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 0f1b10213a0dd7f2ee4c","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\n//Audio and Audio Analysis variables\r\n \r\n//Create an AudioListener and add it to the camera\r\nvar listener = new THREE.AudioListener();\r\n \r\n// create a global audio source\r\nvar sound = new THREE.PositionalAudio( listener );\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n\r\n var audioLoader = new THREE.AudioLoader();\r\n \r\n //Load a sound and set it as the Audio object's buffer\r\n audioLoader.load( 'Dubstep_Sub-Mix_2016.mp3', function( buffer ) {\r\n sound.setBuffer( buffer );\r\n sound.setLoop(true);\r\n sound.setVolume(1.0);\r\n sound.play();\r\n }); \r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n // var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n // gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
      \\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
      \\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
      The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
      \\n \\n
      \\n\\n
      \",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n\t\r\n\tvar target1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);\r\n var composer1 = new EffectComposer(renderer, target1);\r\n var shaderPass1 = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n },\r\n u_cwMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_ccwMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_northMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_southMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_westMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_eastMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateX1: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateY1: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateZ1: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateX2: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateY2: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateZ2: {\r\n type: 'm4v',\r\n value: null\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/firstPass-frag.glsl')\r\n });\r\n \r\n var composer2 = new EffectComposer(renderer);\r\n var shaderPass2 = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_firstPass: {\r\n \ttype: 't',\r\n \tvalue: null\r\n },\r\n u_previousFrame: {\r\n \ttype: 't',\r\n \tvalue: null\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/secondPass-frag.glsl')\r\n });\r\n shaderPass2.renderToScreen = true;\r\n shaderPass2.material.uniforms.u_firstPass.value = composer1.writeBuffer.texture;\r\n \r\n var target3 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);\r\n var composer3 = new EffectComposer(renderer, target3);\r\n var shaderPass3 = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_input: {\r\n \ttype: 't',\r\n \tvalue: null\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/thirdPass-frag.glsl')\r\n });\r\n shaderPass2.material.uniforms.u_previousFrame.value = composer3.writeBuffer.texture;\r\n shaderPass3.material.uniforms.u_input.value = composer1.writeBuffer.texture;\r\n \r\n composer1.addPass(shaderPass1);\r\n composer2.addPass(shaderPass2);\r\n composer3.addPass(shaderPass3);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass1.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n \r\n // Mandelbulb transformation uniforms\r\n var angle = clock.getElapsedTime() / (4.0 * 3.1415); \r\n\r\n var cwMat = new THREE.Matrix4();\r\n cwMat.makeRotationY(angle);\r\n\r\n var ccwMat = new THREE.Matrix4();\r\n ccwMat.makeRotationY(-angle);\r\n\r\n var northMat = new THREE.Matrix4();\r\n northMat.makeRotationX(angle);\r\n\r\n var southMat = new THREE.Matrix4();\r\n southMat.makeRotationX(-angle);\r\n\r\n var eastMat = new THREE.Matrix4();\r\n eastMat.makeRotationZ(angle);\r\n\r\n var westMat = new THREE.Matrix4();\r\n westMat.makeRotationZ(-angle);\r\n\r\n var rotateX1 = new THREE.Matrix4();\r\n rotateX1.makeRotationX(3.1415 / 2.0);\r\n\r\n var rotateY1 = new THREE.Matrix4();\r\n rotateY1.makeRotationY(45.0 * 3.1415 / 180.0);\r\n\r\n var rotateZ1 = new THREE.Matrix4();\r\n rotateZ1.makeRotationZ((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0);\r\n\r\n var rotateX2 = new THREE.Matrix4();\r\n rotateX2.makeRotationX(3.1415 / 2.0);\r\n\r\n var rotateY2 = new THREE.Matrix4();\r\n rotateY2.makeRotationY(-45.0 * 3.1415 / 180.0);\r\n\r\n var rotateZ2 = new THREE.Matrix4();\r\n rotateZ2.makeRotationY((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0);\r\n \r\n shaderPass1.uniforms[\"u_cwMat\"].value = cwMat;\r\n shaderPass1.uniforms[\"u_ccwMat\"].value = ccwMat;\r\n shaderPass1.uniforms[\"u_northMat\"].value = northMat;\r\n shaderPass1.uniforms[\"u_southMat\"].value = southMat;\r\n shaderPass1.uniforms[\"u_westMat\"].value = westMat;\r\n shaderPass1.uniforms[\"u_eastMat\"].value = eastMat;\r\n shaderPass1.uniforms[\"u_rotateX1\"].value = rotateX1;\r\n shaderPass1.uniforms[\"u_rotateY1\"].value = rotateY1;\r\n shaderPass1.uniforms[\"u_rotateZ1\"].value = rotateZ1;\r\n shaderPass1.uniforms[\"u_rotateX2\"].value = rotateX2;\r\n shaderPass1.uniforms[\"u_rotateY2\"].value = rotateY2;\r\n shaderPass1.uniforms[\"u_rotateZ2\"].value = rotateZ2;\r\n \r\n composer1.render();\r\n composer2.render();\r\n composer3.render();\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"/* \\r\\n\\tCode written by Joseph Klinger and Tabatha Hickman\\r\\n\\tUniversity of Pennsylvania\\r\\n\\tCIS 700 Instructor: Rachel Hwang\\r\\n\\tMay 2017\\r\\n*/\\r\\n\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 10.0\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\nuniform mat4 u_cwMat;\\r\\nuniform mat4 u_ccwMat;\\r\\nuniform mat4 u_northMat;\\r\\nuniform mat4 u_southMat;\\r\\nuniform mat4 u_westMat;\\r\\nuniform mat4 u_eastMat;\\r\\nuniform mat4 u_rotateX1;\\r\\nuniform mat4 u_rotateY1;\\r\\nuniform mat4 u_rotateZ1;\\r\\nuniform mat4 u_rotateX2;\\r\\nuniform mat4 u_rotateY2;\\r\\nuniform mat4 u_rotateZ2;\\r\\n\\r\\n\\r\\nvec4 resColor;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t*****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\n// Taken from IQ's realtime ShaderToy implementation here: https://www.shadertoy.com/view/ltfSWn\\r\\nfloat SDF_Mandelbulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i = 0; i < 4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n resColor = trap;\\r\\n\\r\\n return 0.25 * log(m) * sqrt(m) / dz;\\r\\n}\\r\\n\\r\\n// SDF Operators:\\r\\nfloat intersection(float d1, float d2) {\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 ) {\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2) {\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n// Returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform( vec3 point, mat4 trans ) {\\r\\n\\t//columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\nfloat mod(int num1, int num2)\\r\\n{\\r\\n\\tint div = num1/num2;\\r\\n\\treturn float(num1 - div*num2);\\r\\n}\\r\\n\\r\\n// Decide which scene to display (time - dependent)\\r\\nint sceneNum()\\r\\n{\\r\\n\\tfloat x = u_time;\\r\\n\\tfloat cycle = 124.0;\\r\\n\\tfloat fps = 6.0;\\r\\n\\tfloat t = mod(x, cycle);\\r\\n\\tif(t <= 42.0) { return 2; }\\r\\n\\telse if(t <= 80.0) { return 1; }\\r\\n\\telse { return 3; }\\r\\n}\\r\\n\\r\\n// Estimate the distance to the objects in the scene depending on the sceneNum() (see above)\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\tfloat t = u_time/4.0;\\r\\n\\tint sceneNumber = sceneNum();\\r\\n\\r\\n\\tif(sceneNumber == 1)\\r\\n\\t{\\r\\n\\t\\t//SCENE 01------------------------------------------------------------\\r\\n\\t\\tfloat dist1;\\r\\n\\t\\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), u_cwMat), u_northMat);\\t\\r\\n\\t\\tfloat bb1 = SDF_Sphere(newPos1, 1.1);\\r\\n\\t\\tif(bb1 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist1 = SDF_Mandelbulb(newPos1, power);\\r\\n\\t\\t}\\t\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist1 = bb1;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist2;\\r\\n\\t\\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), u_ccwMat), u_eastMat);\\t\\r\\n\\t\\tfloat bb2 = SDF_Sphere(newPos2, 1.1);\\r\\n\\t\\tif(bb2 < .015)\\r\\n\\t\\t{\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist2 = SDF_Mandelbulb(newPos2, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist2 = bb2;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist3;\\r\\n\\t\\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), u_cwMat), u_westMat);\\t\\r\\n\\t\\tfloat bb3 = SDF_Sphere(newPos3, 1.1);\\r\\n\\t\\tif(bb3 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist3 = SDF_Mandelbulb(newPos3, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist3 = bb3;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn un(dist1, un(dist2, dist3));\\r\\n\\t}\\r\\n\\telse if(sceneNumber == 2)\\r\\n\\t{\\r\\n\\t\\t//SCENE 02------------------------------------------------------------\\r\\n\\t\\tfloat dist4;\\r\\n\\t\\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \\r\\n\\t\\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), u_rotateY1), u_rotateZ1), u_rotateX1);\\t\\r\\n\\t\\tfloat bb4 = SDF_Sphere(newPos4, 1.1);\\r\\n\\t\\tif(bb4 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist4 = SDF_Mandelbulb(newPos4, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist4 = bb4;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist4;\\r\\n\\t}\\r\\n\\telse \\r\\n\\t{\\r\\n\\t\\t//SCENE 03------------------------------------------------------------\\r\\n\\t\\tfloat dist5;\\r\\n\\t\\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), u_rotateY2), u_rotateX2), u_rotateZ2);\\t\\r\\n\\t\\tfloat bb5 = SDF_Sphere(newPos5, 1.1);\\r\\n\\t\\tif(bb5 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist5 = SDF_Mandelbulb(newPos5, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist5 = bb5;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist5;\\r\\n\\t}\\r\\n}\\r\\n\\r\\nvec3 backgroundColor() {\\r\\n\\tint sn = sceneNum();\\r\\n\\tfloat darken; \\r\\n\\tif(sn == 1)\\r\\n\\t{\\r\\n\\t\\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\\r\\n\\t\\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\\r\\n\\t}\\r\\n\\telse if(sn == 2)\\r\\n\\t{\\r\\n\\t\\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\\r\\n\\t\\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\\r\\n\\t}\\r\\n\\t\\r\\n\\tdarken = clamp(darken, 0.2, 1.0);\\r\\n\\r\\n\\tvec3 a = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 b = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 c = vec3(2.0, 1.0, 1.0);\\r\\n\\tvec3 d = vec3(0.5, 0.2, 0.25);\\r\\n\\tfloat t = abs(sin(u_time/12.0));\\r\\n\\tvec3 color = a + b*cos(6.28*(c*t + d));\\r\\n\\r\\n\\treturn darken*color;\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\n// Note: this method is slightly less accurate than sampling the scene at pos - epsilon, but because that is an expensive operation for the mandelbulb, we avoid it here\\r\\nvec3 computeNormalFast( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tfloat sampleAtPos = sceneMap(pos);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap(pos + point.xyy) - sampleAtPos,\\r\\n\\t\\t\\t\\t\\tsceneMap(pos + point.yxy) - sampleAtPos,\\r\\n\\t\\t\\t\\t\\tsceneMap(pos + point.yyx) - sampleAtPos));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Taken from a presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\\r\\nfloat ComputeAO( vec3 pos, vec3 normal ) {\\r\\n\\tfloat tStep = 0.0025;\\r\\n\\tfloat diff = 0.0;\\r\\n\\tfloat k = 34.0;\\r\\n\\tfor(float i = 1.0; i <= 5.0; i += 1.0) {\\r\\n\\t\\tvec3 sample = pos + (i * tStep) * normal;\\r\\n\\t\\tfloat dist = sceneMap( sample );\\r\\n\\t\\tdiff += pow(0.5, i) * ((i * tStep) - dist);\\r\\n\\t}\\r\\n\\treturn 1.0 - clamp(k * diff, 0.0, 0.9);\\r\\n}\\r\\n\\r\\n// Convert a fragment coordinate to normalized device coordinates\\r\\nvec2 FragCoordToNDC( vec4 fragCoord ) {\\r\\n\\treturn 2.0 * vec2(fragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t fragCoord.y / u_resolution.y) - 1.0;\\r\\n}\\r\\n\\r\\n// Return the direction of a ray cast through the given point in NDC\\r\\n// This function includes the implementation of the camera; changes to the camera should be made here\\r\\nvec3 Raycast( vec2 p_ndc, vec3 cameraPos ) {\\r\\n\\t\\r\\n\\tfloat len = 10.0;\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos); // Assume we are looking towards (0, 0, 0)\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = p_ndc.x * H + p_ndc.y * V;\\r\\n\\t\\r\\n\\t// Return the direction\\r\\n\\treturn normalize(point_World - cameraPos);\\r\\n}\\r\\n\\r\\n// Referencing the following report: http://celarek.at/wp/wp-content/uploads/2014/05/realTimeFractalsReport.pdf\\r\\nvec3 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\t// Basic Raymarching function: \\r\\n\\tfloat t = 0.01;\\r\\n\\tvec3 result = vec3(0.0);\\r\\n\\t\\r\\n\\tfor(int i = 1; i <= 250; i++) {\\r\\n\\t\\tfloat dist = sceneMap(origin + t * direction);\\r\\n\\t\\t\\r\\n\\t\\tif(abs(dist) < 0.0002) {\\r\\n\\t\\t\\tresult = vec3(t, float (i) / 1000.0, 1.0);\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tresult = vec3(T_MAX, float (i) / 1000.0, 0.0);\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn result;\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n\\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\\r\\n\\tvec2 point_NDC = FragCoordToNDC(gl_FragCoord);\\r\\n\\tvec3 direction = Raycast(point_NDC, cameraPos);\\r\\n\\t\\r\\n\\tvec3 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\tif(isect.z > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormalFast( isectPos );\\r\\n\\t\\tnormal = -normal;\\r\\n\\t\\t\\r\\n\\t\\t// Animated color using orbit traps: see the Mandelbulb SDF by IQ above\\r\\n\\t\\tvec3 trapColor;\\r\\n\\t\\t\\r\\n\\t\\tint sn = sceneNum();\\r\\n\\t\\tif(sn == 1)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(\\r\\n\\t\\t\\t\\tresColor.x-abs(sin((u_time) / 2.0 + isectPos.z) * 0.8), \\r\\n\\t\\t\\t\\tresColor.y-(cos((u_time) / 8.0 + isectPos.y) * 0.5), \\r\\n\\t\\t\\t\\tresColor.z+(cos((u_time) / 2.0 - isectPos.x) * 0.2));\\r\\n\\t\\t}\\r\\n\\t\\telse if(sn == 2)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(resColor) + vec3(0.4);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(0.0, resColor.y + 0.4, resColor.z + 0.4);\\r\\n\\t\\t}\\r\\n\\t\\t\\r\\n\\t\\ttrapColor.r *= 0.01;\\r\\n\\t\\t\\r\\n\\t\\t// Two methods to compute AO:\\r\\n\\t\\tfloat ao = ComputeAO(isectPos, normal);\\r\\n\\t\\t// float fakeAO = 1.0 - clamp(isect.y, 0.0, 0.9);\\r\\n\\t\\t\\r\\n\\t\\tgl_FragColor = ao * vec4(trapColor, 1);\\r\\n\\t\\t// gl_FragColor = fakeAO * vec4(trapColor, 1);\\r\\n\\t} else {\\r\\n\\t\\tgl_FragColor = vec4(backgroundColor(), 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/firstPass-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = \"/* \\r\\n\\tCode written by Joseph Klinger and Tabatha Hickman\\r\\n\\tUniversity of Pennsylvania\\r\\n\\tCIS 700 Instructor: Rachel Hwang\\r\\n\\tMay 2017\\r\\n*/\\r\\n\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 12.0\\r\\n#define MOTION_BLUR true\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform sampler2D u_firstPass;\\r\\nuniform sampler2D u_previousFrame;\\r\\n\\r\\n// The sole purpose of this pass is to compute motion blur between the current and previous frames\\r\\nvoid main() {\\r\\n\\t#ifdef MOTION_BLUR\\r\\n\\t\\tfor(float w = 0.0; w <= 1.0; w += 0.2) {\\r\\n\\t\\t\\tgl_FragColor += (1.0 - w) * texture2D(u_firstPass, f_uv) + w * texture2D(u_previousFrame, f_uv);\\r\\n\\t\\t}\\r\\n\\t\\tgl_FragColor /= 1.0 / 0.2; // divide by the number of samples (1 / stepSize)\\r\\n\\t#else\\r\\n\\t\\tgl_FragColor = texture2D(u_firstPass, f_uv);\\r\\n\\t#endif\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/secondPass-frag.glsl\n// module id = 16\n// module chunks = 0","module.exports = \"/* \\r\\n\\tCode written by Joseph Klinger and Tabatha Hickman\\r\\n\\tUniversity of Pennsylvania\\r\\n\\tCIS 700 Instructor: Rachel Hwang\\r\\n\\tMay 2017\\r\\n*/\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform sampler2D u_input;\\r\\n\\r\\nvoid main() {\\r\\n\\tgl_FragColor = texture2D(u_input, f_uv);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/thirdPass-frag.glsl\n// module id = 17\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 18\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 19\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file From 59b31f232a44c82344d04309ae526b9bc2420fb1 Mon Sep 17 00:00:00 2001 From: Joe Klinger Date: Wed, 3 May 2017 01:12:24 -0400 Subject: [PATCH 20/20] bundle commit --- build/bundle.js | 2 +- build/bundle.js.map | 2 +- src/glsl/firstPass-frag.glsl | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/bundle.js b/build/bundle.js index c789ae7e..58b709cb 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -48623,7 +48623,7 @@ /* 15 */ /***/ (function(module, exports) { - module.exports = "/* \r\n\tCode written by Joseph Klinger and Tabatha Hickman\r\n\tUniversity of Pennsylvania\r\n\tCIS 700 Instructor: Rachel Hwang\r\n\tMay 2017\r\n*/\r\n\r\n#define SPHERE_TRACING true\r\n#define T_MAX 10.0\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\nuniform mat4 u_cwMat;\r\nuniform mat4 u_ccwMat;\r\nuniform mat4 u_northMat;\r\nuniform mat4 u_southMat;\r\nuniform mat4 u_westMat;\r\nuniform mat4 u_eastMat;\r\nuniform mat4 u_rotateX1;\r\nuniform mat4 u_rotateY1;\r\nuniform mat4 u_rotateZ1;\r\nuniform mat4 u_rotateX2;\r\nuniform mat4 u_rotateY2;\r\nuniform mat4 u_rotateZ2;\r\n\r\n\r\nvec4 resColor;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t \t\t\t\t\t\t\t\t\t\t\t*****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\n// Taken from IQ's realtime ShaderToy implementation here: https://www.shadertoy.com/view/ltfSWn\r\nfloat SDF_Mandelbulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i = 0; i < 4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n resColor = trap;\r\n\r\n return 0.25 * log(m) * sqrt(m) / dz;\r\n}\r\n\r\n// SDF Operators:\r\nfloat intersection(float d1, float d2) {\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 ) {\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2) {\r\n return min(d1,d2);\r\n}\r\n\r\n// Returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform( vec3 point, mat4 trans ) {\r\n\t//columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\nfloat mod(int num1, int num2)\r\n{\r\n\tint div = num1/num2;\r\n\treturn float(num1 - div*num2);\r\n}\r\n\r\n// Decide which scene to display (time - dependent)\r\nint sceneNum()\r\n{\r\n\tfloat x = u_time;\r\n\tfloat cycle = 124.0;\r\n\tfloat fps = 6.0;\r\n\tfloat t = mod(x, cycle);\r\n\tif(t <= 42.0) { return 2; }\r\n\telse if(t <= 80.0) { return 1; }\r\n\telse { return 3; }\r\n}\r\n\r\n// Estimate the distance to the objects in the scene depending on the sceneNum() (see above)\r\nfloat sceneMap( vec3 pos ) {\r\n\tfloat t = u_time/4.0;\r\n\tint sceneNumber = sceneNum();\r\n\r\n\tif(sceneNumber == 1)\r\n\t{\r\n\t\t//SCENE 01------------------------------------------------------------\r\n\t\tfloat dist1;\r\n\t\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), u_cwMat), u_northMat);\t\r\n\t\tfloat bb1 = SDF_Sphere(newPos1, 1.1);\r\n\t\tif(bb1 < .015)\r\n\t\t{\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist1 = SDF_Mandelbulb(newPos1, power);\r\n\t\t}\t\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist1 = bb1;\r\n\t\t}\r\n\r\n\t\tfloat dist2;\r\n\t\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), u_ccwMat), u_eastMat);\t\r\n\t\tfloat bb2 = SDF_Sphere(newPos2, 1.1);\r\n\t\tif(bb2 < .015)\r\n\t\t{\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist2 = SDF_Mandelbulb(newPos2, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist2 = bb2;\r\n\t\t}\r\n\r\n\t\tfloat dist3;\r\n\t\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), u_cwMat), u_westMat);\t\r\n\t\tfloat bb3 = SDF_Sphere(newPos3, 1.1);\r\n\t\tif(bb3 < .015)\r\n\t\t{\r\n\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist3 = SDF_Mandelbulb(newPos3, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist3 = bb3;\r\n\t\t}\r\n\r\n\t\treturn un(dist1, un(dist2, dist3));\r\n\t}\r\n\telse if(sceneNumber == 2)\r\n\t{\r\n\t\t//SCENE 02------------------------------------------------------------\r\n\t\tfloat dist4;\r\n\t\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \r\n\t\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), u_rotateY1), u_rotateZ1), u_rotateX1);\t\r\n\t\tfloat bb4 = SDF_Sphere(newPos4, 1.1);\r\n\t\tif(bb4 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist4 = SDF_Mandelbulb(newPos4, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist4 = bb4;\r\n\t\t}\r\n\r\n\t\treturn dist4;\r\n\t}\r\n\telse \r\n\t{\r\n\t\t//SCENE 03------------------------------------------------------------\r\n\t\tfloat dist5;\r\n\t\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), u_rotateY2), u_rotateX2), u_rotateZ2);\t\r\n\t\tfloat bb5 = SDF_Sphere(newPos5, 1.1);\r\n\t\tif(bb5 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist5 = SDF_Mandelbulb(newPos5, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist5 = bb5;\r\n\t\t}\r\n\r\n\t\treturn dist5;\r\n\t}\r\n}\r\n\r\nvec3 backgroundColor() {\r\n\tint sn = sceneNum();\r\n\tfloat darken; \r\n\tif(sn == 1)\r\n\t{\r\n\t\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\r\n\t\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\r\n\t}\r\n\telse if(sn == 2)\r\n\t{\r\n\t\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\r\n\t\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\r\n\t}\r\n\t\r\n\tdarken = clamp(darken, 0.2, 1.0);\r\n\r\n\tvec3 a = vec3(0.5, 0.5, 0.5);\r\n\tvec3 b = vec3(0.5, 0.5, 0.5);\r\n\tvec3 c = vec3(2.0, 1.0, 1.0);\r\n\tvec3 d = vec3(0.5, 0.2, 0.25);\r\n\tfloat t = abs(sin(u_time/12.0));\r\n\tvec3 color = a + b*cos(6.28*(c*t + d));\r\n\r\n\treturn darken*color;\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\n// Note: this method is slightly less accurate than sampling the scene at pos - epsilon, but because that is an expensive operation for the mandelbulb, we avoid it here\r\nvec3 computeNormalFast( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tfloat sampleAtPos = sceneMap(pos);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap(pos + point.xyy) - sampleAtPos,\r\n\t\t\t\t\tsceneMap(pos + point.yxy) - sampleAtPos,\r\n\t\t\t\t\tsceneMap(pos + point.yyx) - sampleAtPos));\r\n\treturn normal;\r\n}\r\n\r\n// Taken from a presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\r\nfloat ComputeAO( vec3 pos, vec3 normal ) {\r\n\tfloat tStep = 0.0025;\r\n\tfloat diff = 0.0;\r\n\tfloat k = 34.0;\r\n\tfor(float i = 1.0; i <= 5.0; i += 1.0) {\r\n\t\tvec3 sample = pos + (i * tStep) * normal;\r\n\t\tfloat dist = sceneMap( sample );\r\n\t\tdiff += pow(0.5, i) * ((i * tStep) - dist);\r\n\t}\r\n\treturn 1.0 - clamp(k * diff, 0.0, 0.9);\r\n}\r\n\r\n// Convert a fragment coordinate to normalized device coordinates\r\nvec2 FragCoordToNDC( vec4 fragCoord ) {\r\n\treturn 2.0 * vec2(fragCoord.x / u_resolution.x,\r\n\t\t\t\t\t fragCoord.y / u_resolution.y) - 1.0;\r\n}\r\n\r\n// Return the direction of a ray cast through the given point in NDC\r\n// This function includes the implementation of the camera; changes to the camera should be made here\r\nvec3 Raycast( vec2 p_ndc, vec3 cameraPos ) {\r\n\t\r\n\tfloat len = 10.0;\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos); // Assume we are looking towards (0, 0, 0)\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = p_ndc.x * H + p_ndc.y * V;\r\n\t\r\n\t// Return the direction\r\n\treturn normalize(point_World - cameraPos);\r\n}\r\n\r\n// Referencing the following report: http://celarek.at/wp/wp-content/uploads/2014/05/realTimeFractalsReport.pdf\r\nvec3 raymarchScene( vec3 origin, vec3 direction ) {\r\n\t// Basic Raymarching function: \r\n\tfloat t = 0.01;\r\n\tvec3 result = vec3(0.0);\r\n\t\r\n\tfor(int i = 1; i <= 250; i++) {\r\n\t\tfloat dist = sceneMap(origin + t * direction);\r\n\t\t\r\n\t\tif(abs(dist) < 0.0002) {\r\n\t\t\tresult = vec3(t, float (i) / 1000.0, 1.0);\r\n\t\t\tbreak;\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tresult = vec3(T_MAX, float (i) / 1000.0, 0.0);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn result;\r\n}\r\n\r\nvoid main() {\r\n\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\r\n\tvec2 point_NDC = FragCoordToNDC(gl_FragCoord);\r\n\tvec3 direction = Raycast(point_NDC, cameraPos);\r\n\t\r\n\tvec3 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\tif(isect.z > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormalFast( isectPos );\r\n\t\tnormal = -normal;\r\n\t\t\r\n\t\t// Animated color using orbit traps: see the Mandelbulb SDF by IQ above\r\n\t\tvec3 trapColor;\r\n\t\t\r\n\t\tint sn = sceneNum();\r\n\t\tif(sn == 1)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(\r\n\t\t\t\tresColor.x-abs(sin((u_time) / 2.0 + isectPos.z) * 0.8), \r\n\t\t\t\tresColor.y-(cos((u_time) / 8.0 + isectPos.y) * 0.5), \r\n\t\t\t\tresColor.z+(cos((u_time) / 2.0 - isectPos.x) * 0.2));\r\n\t\t}\r\n\t\telse if(sn == 2)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(resColor) + vec3(0.4);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\ttrapColor = vec3(0.0, resColor.y + 0.4, resColor.z + 0.4);\r\n\t\t}\r\n\t\t\r\n\t\ttrapColor.r *= 0.01;\r\n\t\t\r\n\t\t// Two methods to compute AO:\r\n\t\tfloat ao = ComputeAO(isectPos, normal);\r\n\t\t// float fakeAO = 1.0 - clamp(isect.y, 0.0, 0.9);\r\n\t\t\r\n\t\tgl_FragColor = ao * vec4(trapColor, 1);\r\n\t\t// gl_FragColor = fakeAO * vec4(trapColor, 1);\r\n\t} else {\r\n\t\tgl_FragColor = vec4(backgroundColor(), 1);\r\n\t}\r\n}\r\n" + module.exports = "/* \r\n\tCode written by Joseph Klinger and Tabatha Hickman\r\n\tUniversity of Pennsylvania\r\n\tCIS 700 Instructor: Rachel Hwang\r\n\tMay 2017\r\n*/\r\n\r\n#define SPHERE_TRACING true\r\n#define T_MAX 10.0\r\n\r\nvarying vec2 f_uv;\r\n\r\nuniform float u_time;\r\nuniform vec2 u_resolution;\r\nuniform float u_fovy;\r\nuniform float u_aspect;\r\n\r\nuniform mat4 u_cwMat;\r\nuniform mat4 u_ccwMat;\r\nuniform mat4 u_northMat;\r\nuniform mat4 u_southMat;\r\nuniform mat4 u_westMat;\r\nuniform mat4 u_eastMat;\r\nuniform mat4 u_rotateX1;\r\nuniform mat4 u_rotateY1;\r\nuniform mat4 u_rotateZ1;\r\nuniform mat4 u_rotateX2;\r\nuniform mat4 u_rotateY2;\r\nuniform mat4 u_rotateZ2;\r\n\r\n\r\nvec4 resColor;\r\n\r\n/***** Geometry SDF Functions\r\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\r\n\t\t\t\t\t\t\t \t\t\t\t\t\t\t\t\t\t\t*****/\r\n\r\nfloat SDF_Sphere( vec3 pos, float radius ) {\r\n\treturn length(pos) - radius;\r\n}\r\n\r\n// Taken from IQ's realtime ShaderToy implementation here: https://www.shadertoy.com/view/ltfSWn\r\nfloat SDF_Mandelbulb( vec3 p , float manPower)\r\n{\r\n\tvec3 w = p;\r\n float m = dot(w,w);\r\n\r\n vec4 trap = vec4(abs(w),m);\r\n float dz = 1.0;\r\n \r\n \r\n for( int i = 0; i < 4; i++ )\r\n {\r\n#if 1\r\n float m2 = m*m;\r\n float m4 = m2*m2;\r\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\r\n\r\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\r\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\r\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\r\n\r\n float k3 = x2 + z2;\r\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\r\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\r\n float k4 = x2 - y2 + z2;\r\n\r\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\r\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\r\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\r\n#else\r\n dz = 8.0*pow(m,3.5)*dz + 1.0;\r\n \r\n float r = length(w);\r\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\r\n float a = 8.0*atan( w.x, w.z );\r\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\r\n#endif \r\n \r\n trap = min( trap, vec4(abs(w),m) );\r\n\r\n m = dot(w,w);\r\n if( m > 4.0 )\r\n break;\r\n }\r\n trap.x = m;\r\n resColor = trap;\r\n\r\n return 0.25 * log(m) * sqrt(m) / dz;\r\n}\r\n\r\n// SDF Operators:\r\nfloat intersection(float d1, float d2) {\r\n return max(d1,d2);\r\n}\r\n\r\nfloat subtraction( float d1, float d2 ) {\r\n return max(-d1,d2);\r\n}\r\n\r\nfloat un(float d1, float d2) {\r\n return min(d1,d2);\r\n}\r\n\r\n// Returns transformed point based on rotation and translation matrix of shape\r\nvec3 transform( vec3 point, mat4 trans ) {\r\n\t//columns of the rotation matrix transpose\r\n\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\r\n\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\r\n\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\r\n\r\n\tmat3 rotTranspose = mat3(col1, col2, col3);\r\n\r\n\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\r\n\r\n\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\r\n\r\n\treturn vec3(newTrans * vec4(point, 1.0));\r\n}\r\n\r\nfloat mod(int num1, int num2)\r\n{\r\n\tint div = num1/num2;\r\n\treturn float(num1 - div*num2);\r\n}\r\n\r\n// Decide which scene to display (time - dependent)\r\nint sceneNum()\r\n{\r\n\tfloat x = u_time;\r\n\tfloat cycle = 124.0;\r\n\tfloat fps = 6.0;\r\n\tfloat t = mod(x, cycle);\r\n\tif(t <= 42.0) { return 2; }\r\n\telse if(t <= 80.0) { return 1; }\r\n\telse { return 3; }\r\n}\r\n\r\n// Estimate the distance to the objects in the scene depending on the sceneNum() (see above)\r\nfloat sceneMap( vec3 pos ) {\r\n\tfloat t = u_time/4.0;\r\n\tint sceneNumber = sceneNum();\r\n\r\n\tif(sceneNumber == 1)\r\n\t{\r\n\t\t//SCENE 01------------------------------------------------------------\r\n\t\tfloat dist1;\r\n\t\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), u_cwMat), u_northMat);\t\r\n\t\tfloat bb1 = SDF_Sphere(newPos1, 1.1);\r\n\t\tif(bb1 < .015)\r\n\t\t{\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist1 = SDF_Mandelbulb(newPos1, power);\r\n\t\t}\t\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist1 = bb1;\r\n\t\t}\r\n\r\n\t\tfloat dist2;\r\n\t\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), u_ccwMat), u_eastMat);\t\r\n\t\tfloat bb2 = SDF_Sphere(newPos2, 1.1);\r\n\t\tif(bb2 < .015)\r\n\t\t{\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist2 = SDF_Mandelbulb(newPos2, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist2 = bb2;\r\n\t\t}\r\n\r\n\t\tfloat dist3;\r\n\t\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), u_cwMat), u_westMat);\t\r\n\t\tfloat bb3 = SDF_Sphere(newPos3, 1.1);\r\n\t\tif(bb3 < .015)\r\n\t\t{\r\n\t\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist3 = SDF_Mandelbulb(newPos3, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist3 = bb3;\r\n\t\t}\r\n\r\n\t\treturn un(dist1, un(dist2, dist3));\r\n\t}\r\n\telse if(sceneNumber == 2)\r\n\t{\r\n\t\t//SCENE 02------------------------------------------------------------\r\n\t\tfloat dist4;\r\n\t\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \r\n\t\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), u_rotateY1), u_rotateZ1), u_rotateX1);\t\r\n\t\tfloat bb4 = SDF_Sphere(newPos4, 1.1);\r\n\t\tif(bb4 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist4 = SDF_Mandelbulb(newPos4, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist4 = bb4;\r\n\t\t}\r\n\r\n\t\treturn dist4;\r\n\t}\r\n\telse \r\n\t{\r\n\t\t//SCENE 03------------------------------------------------------------\r\n\t\tfloat dist5;\r\n\t\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), u_rotateY2), u_rotateX2), u_rotateZ2);\t\r\n\t\tfloat bb5 = SDF_Sphere(newPos5, 1.1);\r\n\t\tif(bb5 < .015)\r\n\t\t{\t\r\n\t\t\tfloat power = 10.0;\r\n\t\t\tdist5 = SDF_Mandelbulb(newPos5, power);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tdist5 = bb5;\r\n\t\t}\r\n\r\n\t\treturn dist5;\r\n\t}\r\n}\r\n\r\nvec3 backgroundColor() {\r\n\tint sn = sceneNum();\r\n\tfloat darken; \r\n\tif(sn == 1)\r\n\t{\r\n\t\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\r\n\t\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\r\n\t}\r\n\telse if(sn == 2)\r\n\t{\r\n\t\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\r\n\t}\r\n\telse\r\n\t{\r\n\t\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\r\n\t\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\r\n\t}\r\n\t\r\n\tdarken = clamp(darken, 0.2, 1.0);\r\n\r\n\tvec3 a = vec3(0.5, 0.5, 0.5);\r\n\tvec3 b = vec3(0.5, 0.5, 0.5);\r\n\tvec3 c = vec3(2.0, 1.0, 1.0);\r\n\tvec3 d = vec3(0.5, 0.2, 0.25);\r\n\tfloat t = abs(sin(u_time/12.0));\r\n\tvec3 color = a + b*cos(6.28*(c*t + d));\r\n\r\n\treturn darken*color;\r\n}\r\n\r\n// Compute the normal of an implicit surface using the gradient method\r\n// Note: this method is slightly less accurate than sampling the scene at pos - epsilon, but because that is an expensive operation for the mandelbulb, we avoid it here\r\nvec3 computeNormalFast( vec3 pos ) {\r\n\tvec2 point = vec2(0.0001, 0.0);\r\n\tfloat sampleAtPos = sceneMap(pos);\r\n\tvec3 normal = normalize(\r\n\t\t\t vec3(sceneMap(pos + point.xyy) - sampleAtPos,\r\n\t\t\t\t\tsceneMap(pos + point.yxy) - sampleAtPos,\r\n\t\t\t\t\tsceneMap(pos + point.yyx) - sampleAtPos));\r\n\treturn normal;\r\n}\r\n\r\n// Taken from a presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\r\nfloat ComputeAO( vec3 pos, vec3 normal ) {\r\n\tfloat tStep = 0.0025;\r\n\tfloat diff = 0.0;\r\n\tfloat k = 34.0;\r\n\tfor(float i = 1.0; i <= 5.0; i += 1.0) {\r\n\t\tvec3 sample = pos + (i * tStep) * normal;\r\n\t\tfloat dist = sceneMap( sample );\r\n\t\tdiff += pow(0.5, i) * ((i * tStep) - dist);\r\n\t}\r\n\treturn 1.0 - clamp(k * diff, 0.0, 0.9);\r\n}\r\n\r\n// Convert a fragment coordinate to normalized device coordinates\r\nvec2 FragCoordToNDC( vec4 fragCoord ) {\r\n\treturn 2.0 * vec2(fragCoord.x / u_resolution.x,\r\n\t\t\t\t\t fragCoord.y / u_resolution.y) - 1.0;\r\n}\r\n\r\n// Return the direction of a ray cast through the given point in NDC\r\n// This function includes the implementation of the camera; changes to the camera should be made here\r\nvec3 Raycast( vec2 p_ndc, vec3 cameraPos ) {\r\n\t\r\n\tfloat len = 10.0;\r\n\t\r\n\t// Compute camera's frame of reference\r\n\tvec3 look = normalize(-cameraPos); // Assume we are looking towards (0, 0, 0)\r\n\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\r\n\tvec3 up = normalize(cross(right, look));\r\n\t\r\n\tfloat tanAlpha = tan(u_fovy / 2.0);\r\n\tvec3 V = up * len * tanAlpha;\r\n\tvec3 H = right * len * u_aspect * tanAlpha;\r\n\t\r\n\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\r\n\tvec3 point_World = p_ndc.x * H + p_ndc.y * V;\r\n\t\r\n\t// Return the direction\r\n\treturn normalize(point_World - cameraPos);\r\n}\r\n\r\n// Referencing the following report: http://celarek.at/wp/wp-content/uploads/2014/05/realTimeFractalsReport.pdf\r\nvec3 raymarchScene( vec3 origin, vec3 direction ) {\r\n\t// Basic Raymarching function: \r\n\tfloat t = 0.01;\r\n\tvec3 result = vec3(0.0);\r\n\t\r\n\tfor(int i = 1; i <= 750; i++) {\r\n\t\tfloat dist = sceneMap(origin + t * direction);\r\n\t\t\r\n\t\tif(abs(dist) < 0.0002) {\r\n\t\t\tresult = vec3(t, float (i) / 1000.0, 1.0);\r\n\t\t\tbreak;\r\n\t\t} else if(t > T_MAX) {\r\n\t\t\tresult = vec3(T_MAX, float (i) / 1000.0, 0.0);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t\r\n\t\t#ifdef SPHERE_TRACING\r\n\t\t\tt += dist;\r\n\t\t#else\r\n\t\t\tt += 0.01;\r\n\t\t#endif\r\n\t}\r\n\treturn result;\r\n}\r\n\r\nvoid main() {\r\n\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\r\n\tvec2 point_NDC = FragCoordToNDC(gl_FragCoord);\r\n\tvec3 direction = Raycast(point_NDC, cameraPos);\r\n\t\r\n\tvec3 isect = raymarchScene( cameraPos, direction );\r\n\tvec3 isectPos = cameraPos + isect.x * direction;\r\n\t\r\n\tif(isect.z > 0.0) { // we did intersect with something\r\n\t\tvec3 normal = computeNormalFast( isectPos );\r\n\t\tnormal = -normal;\r\n\t\t\r\n\t\t// Animated color using orbit traps: see the Mandelbulb SDF by IQ above\r\n\t\tvec3 trapColor;\r\n\t\t\r\n\t\tint sn = sceneNum();\r\n\t\tif(sn == 1)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(\r\n\t\t\t\tresColor.x-abs(sin((u_time) / 2.0 + isectPos.z) * 0.8), \r\n\t\t\t\tresColor.y-(cos((u_time) / 8.0 + isectPos.y) * 0.5), \r\n\t\t\t\tresColor.z+(cos((u_time) / 2.0 - isectPos.x) * 0.2));\r\n\t\t}\r\n\t\telse if(sn == 2)\r\n\t\t{\r\n\t\t\ttrapColor = vec3(resColor) + vec3(0.4);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\ttrapColor = vec3(0.0, resColor.y + 0.4, resColor.z + 0.4);\r\n\t\t}\r\n\t\t\r\n\t\ttrapColor.r *= 0.01;\r\n\t\t\r\n\t\t// Two methods to compute AO:\r\n\t\t// float ao = ComputeAO(isectPos, normal);\r\n\t\tfloat fakeAO = 1.0 - clamp(isect.y, 0.0, 0.9);\r\n\t\t\r\n\t\t// gl_FragColor = ao * vec4(trapColor, 1);\r\n\t\tgl_FragColor = fakeAO * vec4(trapColor, 1);\r\n\t} else {\r\n\t\tgl_FragColor = vec4(backgroundColor(), 1);\r\n\t}\r\n}\r\n" /***/ }), /* 16 */ diff --git a/build/bundle.js.map b/build/bundle.js.map index 525bc541..eb7cdda4 100644 --- a/build/bundle.js.map +++ b/build/bundle.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 0f1b10213a0dd7f2ee4c","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/firstPass-frag.glsl","webpack:///./src/glsl/secondPass-frag.glsl","webpack:///./src/glsl/thirdPass-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","listener","AudioListener","sound","PositionalAudio","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","audioLoader","AudioLoader","load","buffer","setBuffer","setLoop","setVolume","play","aspect","updateProjectionMatrix","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","target1","WebGLRenderTarget","composer1","shaderPass1","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","u_cwMat","u_ccwMat","u_northMat","u_southMat","u_westMat","u_eastMat","u_rotateX1","u_rotateY1","u_rotateZ1","u_rotateX2","u_rotateY2","u_rotateZ2","vertexShader","fragmentShader","composer2","shaderPass2","u_firstPass","u_previousFrame","renderToScreen","material","writeBuffer","texture","target3","composer3","shaderPass3","u_input","addPass","getElapsedTime","angle","cwMat","Matrix4","makeRotationY","ccwMat","northMat","makeRotationX","southMat","eastMat","makeRotationZ","westMat","rotateX1","rotateY1","rotateZ1","rotateX2","rotateY2","rotateZ2"],"mappings":"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AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,SAAQ,OAAO;AACf;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA,qEAAoE,iCAAiC;;AAErG;;AAEA;AACA;;;;AAIA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA,WAAU,iDAAiD,gBAAgB,uBAAuB,2BAA2B,qBAAqB,qBAAqB,GAAG,gBAAgB,yBAAyB,2BAA2B,gBAAgB,wBAAwB,yBAAyB,+BAA+B,GAAG,sBAAsB,0BAA0B,uBAAuB,2BAA2B,4BAA4B,gBAAgB,iBAAiB,uBAAuB,qBAAqB,kBAAkB,iBAAiB,GAAG;;;AAGlkB;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;;AAEA;AACA;AACA,4C;AACA,YAAW;AACX;AACA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AA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AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA,sBAAqB,mGAAmG,aAAa,2CAA2C,mBAAmB,SAAS,KAAK,4BAA4B,YAAY,gBAAgB,oCAAoC,WAAW,qCAAqC,gBAAgB,uBAAuB,iBAAiB,oCAAoC,eAAe,4BAA4B,uCAAuC,cAAc,iBAAiB;AAC1iB,mBAAkB,iBAAiB,oCAAoC,gBAAgB,mCAAmC,WAAW,YAAY,uBAAuB,qBAAqB,qBAAqB,EAAE,qCAAqC,2BAA2B,YAAY,WAAW,uBAAuB,iBAAiB,oCAAoC,UAAU,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EA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,sBAAsB;;AAE5D;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4BAA2B;;;AAG3B;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAE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AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG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AiH,sDAAsD,oLAAoL,yJAAyJ,GAAG;;AAEjjB,oJAAmJ,sDAAsD,mMAAmM,6PAA6P,4TAA4T,WAAW;;AAEh9B,0CAAyC,wBAAwB,+QAA+Q,4EAA4E,iDAAiD,0KAA0K,yDAAyD,6IAA6I;;AAE7zB,wCAAuC,sBAAsB,0MAA0M,wKAAwK,mCAAmC,yKAAyK;;AAE3nB,2CAA0C,yKAAyK,8EAA8E,GAAG;;AAEpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;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;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;A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AEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;A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AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA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A;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;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;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,sBAAqB,eAAe;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;AAEA,wCAAuC,SAAS;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 0f1b10213a0dd7f2ee4c","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\n//Audio and Audio Analysis variables\r\n \r\n//Create an AudioListener and add it to the camera\r\nvar listener = new THREE.AudioListener();\r\n \r\n// create a global audio source\r\nvar sound = new THREE.PositionalAudio( listener );\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n\r\n var audioLoader = new THREE.AudioLoader();\r\n \r\n //Load a sound and set it as the Audio object's buffer\r\n audioLoader.load( 'Dubstep_Sub-Mix_2016.mp3', function( buffer ) {\r\n sound.setBuffer( buffer );\r\n sound.setLoop(true);\r\n sound.setVolume(1.0);\r\n sound.play();\r\n }); \r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n // var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n // gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
      \\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
      \\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
      The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
      \\n \\n
      \\n\\n
      \",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n\t\r\n\tvar target1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);\r\n var composer1 = new EffectComposer(renderer, target1);\r\n var shaderPass1 = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n },\r\n u_cwMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_ccwMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_northMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_southMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_westMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_eastMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateX1: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateY1: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateZ1: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateX2: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateY2: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateZ2: {\r\n type: 'm4v',\r\n value: null\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/firstPass-frag.glsl')\r\n });\r\n \r\n var composer2 = new EffectComposer(renderer);\r\n var shaderPass2 = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_firstPass: {\r\n \ttype: 't',\r\n \tvalue: null\r\n },\r\n u_previousFrame: {\r\n \ttype: 't',\r\n \tvalue: null\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/secondPass-frag.glsl')\r\n });\r\n shaderPass2.renderToScreen = true;\r\n shaderPass2.material.uniforms.u_firstPass.value = composer1.writeBuffer.texture;\r\n \r\n var target3 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);\r\n var composer3 = new EffectComposer(renderer, target3);\r\n var shaderPass3 = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_input: {\r\n \ttype: 't',\r\n \tvalue: null\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/thirdPass-frag.glsl')\r\n });\r\n shaderPass2.material.uniforms.u_previousFrame.value = composer3.writeBuffer.texture;\r\n shaderPass3.material.uniforms.u_input.value = composer1.writeBuffer.texture;\r\n \r\n composer1.addPass(shaderPass1);\r\n composer2.addPass(shaderPass2);\r\n composer3.addPass(shaderPass3);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass1.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n \r\n // Mandelbulb transformation uniforms\r\n var angle = clock.getElapsedTime() / (4.0 * 3.1415); \r\n\r\n var cwMat = new THREE.Matrix4();\r\n cwMat.makeRotationY(angle);\r\n\r\n var ccwMat = new THREE.Matrix4();\r\n ccwMat.makeRotationY(-angle);\r\n\r\n var northMat = new THREE.Matrix4();\r\n northMat.makeRotationX(angle);\r\n\r\n var southMat = new THREE.Matrix4();\r\n southMat.makeRotationX(-angle);\r\n\r\n var eastMat = new THREE.Matrix4();\r\n eastMat.makeRotationZ(angle);\r\n\r\n var westMat = new THREE.Matrix4();\r\n westMat.makeRotationZ(-angle);\r\n\r\n var rotateX1 = new THREE.Matrix4();\r\n rotateX1.makeRotationX(3.1415 / 2.0);\r\n\r\n var rotateY1 = new THREE.Matrix4();\r\n rotateY1.makeRotationY(45.0 * 3.1415 / 180.0);\r\n\r\n var rotateZ1 = new THREE.Matrix4();\r\n rotateZ1.makeRotationZ((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0);\r\n\r\n var rotateX2 = new THREE.Matrix4();\r\n rotateX2.makeRotationX(3.1415 / 2.0);\r\n\r\n var rotateY2 = new THREE.Matrix4();\r\n rotateY2.makeRotationY(-45.0 * 3.1415 / 180.0);\r\n\r\n var rotateZ2 = new THREE.Matrix4();\r\n rotateZ2.makeRotationY((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0);\r\n \r\n shaderPass1.uniforms[\"u_cwMat\"].value = cwMat;\r\n shaderPass1.uniforms[\"u_ccwMat\"].value = ccwMat;\r\n shaderPass1.uniforms[\"u_northMat\"].value = northMat;\r\n shaderPass1.uniforms[\"u_southMat\"].value = southMat;\r\n shaderPass1.uniforms[\"u_westMat\"].value = westMat;\r\n shaderPass1.uniforms[\"u_eastMat\"].value = eastMat;\r\n shaderPass1.uniforms[\"u_rotateX1\"].value = rotateX1;\r\n shaderPass1.uniforms[\"u_rotateY1\"].value = rotateY1;\r\n shaderPass1.uniforms[\"u_rotateZ1\"].value = rotateZ1;\r\n shaderPass1.uniforms[\"u_rotateX2\"].value = rotateX2;\r\n shaderPass1.uniforms[\"u_rotateY2\"].value = rotateY2;\r\n shaderPass1.uniforms[\"u_rotateZ2\"].value = rotateZ2;\r\n \r\n composer1.render();\r\n composer2.render();\r\n composer3.render();\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"/* \\r\\n\\tCode written by Joseph Klinger and Tabatha Hickman\\r\\n\\tUniversity of Pennsylvania\\r\\n\\tCIS 700 Instructor: Rachel Hwang\\r\\n\\tMay 2017\\r\\n*/\\r\\n\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 10.0\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\nuniform mat4 u_cwMat;\\r\\nuniform mat4 u_ccwMat;\\r\\nuniform mat4 u_northMat;\\r\\nuniform mat4 u_southMat;\\r\\nuniform mat4 u_westMat;\\r\\nuniform mat4 u_eastMat;\\r\\nuniform mat4 u_rotateX1;\\r\\nuniform mat4 u_rotateY1;\\r\\nuniform mat4 u_rotateZ1;\\r\\nuniform mat4 u_rotateX2;\\r\\nuniform mat4 u_rotateY2;\\r\\nuniform mat4 u_rotateZ2;\\r\\n\\r\\n\\r\\nvec4 resColor;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t*****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\n// Taken from IQ's realtime ShaderToy implementation here: https://www.shadertoy.com/view/ltfSWn\\r\\nfloat SDF_Mandelbulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i = 0; i < 4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n resColor = trap;\\r\\n\\r\\n return 0.25 * log(m) * sqrt(m) / dz;\\r\\n}\\r\\n\\r\\n// SDF Operators:\\r\\nfloat intersection(float d1, float d2) {\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 ) {\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2) {\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n// Returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform( vec3 point, mat4 trans ) {\\r\\n\\t//columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\nfloat mod(int num1, int num2)\\r\\n{\\r\\n\\tint div = num1/num2;\\r\\n\\treturn float(num1 - div*num2);\\r\\n}\\r\\n\\r\\n// Decide which scene to display (time - dependent)\\r\\nint sceneNum()\\r\\n{\\r\\n\\tfloat x = u_time;\\r\\n\\tfloat cycle = 124.0;\\r\\n\\tfloat fps = 6.0;\\r\\n\\tfloat t = mod(x, cycle);\\r\\n\\tif(t <= 42.0) { return 2; }\\r\\n\\telse if(t <= 80.0) { return 1; }\\r\\n\\telse { return 3; }\\r\\n}\\r\\n\\r\\n// Estimate the distance to the objects in the scene depending on the sceneNum() (see above)\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\tfloat t = u_time/4.0;\\r\\n\\tint sceneNumber = sceneNum();\\r\\n\\r\\n\\tif(sceneNumber == 1)\\r\\n\\t{\\r\\n\\t\\t//SCENE 01------------------------------------------------------------\\r\\n\\t\\tfloat dist1;\\r\\n\\t\\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), u_cwMat), u_northMat);\\t\\r\\n\\t\\tfloat bb1 = SDF_Sphere(newPos1, 1.1);\\r\\n\\t\\tif(bb1 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist1 = SDF_Mandelbulb(newPos1, power);\\r\\n\\t\\t}\\t\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist1 = bb1;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist2;\\r\\n\\t\\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), u_ccwMat), u_eastMat);\\t\\r\\n\\t\\tfloat bb2 = SDF_Sphere(newPos2, 1.1);\\r\\n\\t\\tif(bb2 < .015)\\r\\n\\t\\t{\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist2 = SDF_Mandelbulb(newPos2, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist2 = bb2;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist3;\\r\\n\\t\\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), u_cwMat), u_westMat);\\t\\r\\n\\t\\tfloat bb3 = SDF_Sphere(newPos3, 1.1);\\r\\n\\t\\tif(bb3 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist3 = SDF_Mandelbulb(newPos3, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist3 = bb3;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn un(dist1, un(dist2, dist3));\\r\\n\\t}\\r\\n\\telse if(sceneNumber == 2)\\r\\n\\t{\\r\\n\\t\\t//SCENE 02------------------------------------------------------------\\r\\n\\t\\tfloat dist4;\\r\\n\\t\\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \\r\\n\\t\\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), u_rotateY1), u_rotateZ1), u_rotateX1);\\t\\r\\n\\t\\tfloat bb4 = SDF_Sphere(newPos4, 1.1);\\r\\n\\t\\tif(bb4 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist4 = SDF_Mandelbulb(newPos4, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist4 = bb4;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist4;\\r\\n\\t}\\r\\n\\telse \\r\\n\\t{\\r\\n\\t\\t//SCENE 03------------------------------------------------------------\\r\\n\\t\\tfloat dist5;\\r\\n\\t\\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), u_rotateY2), u_rotateX2), u_rotateZ2);\\t\\r\\n\\t\\tfloat bb5 = SDF_Sphere(newPos5, 1.1);\\r\\n\\t\\tif(bb5 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist5 = SDF_Mandelbulb(newPos5, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist5 = bb5;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist5;\\r\\n\\t}\\r\\n}\\r\\n\\r\\nvec3 backgroundColor() {\\r\\n\\tint sn = sceneNum();\\r\\n\\tfloat darken; \\r\\n\\tif(sn == 1)\\r\\n\\t{\\r\\n\\t\\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\\r\\n\\t\\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\\r\\n\\t}\\r\\n\\telse if(sn == 2)\\r\\n\\t{\\r\\n\\t\\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\\r\\n\\t\\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\\r\\n\\t}\\r\\n\\t\\r\\n\\tdarken = clamp(darken, 0.2, 1.0);\\r\\n\\r\\n\\tvec3 a = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 b = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 c = vec3(2.0, 1.0, 1.0);\\r\\n\\tvec3 d = vec3(0.5, 0.2, 0.25);\\r\\n\\tfloat t = abs(sin(u_time/12.0));\\r\\n\\tvec3 color = a + b*cos(6.28*(c*t + d));\\r\\n\\r\\n\\treturn darken*color;\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\n// Note: this method is slightly less accurate than sampling the scene at pos - epsilon, but because that is an expensive operation for the mandelbulb, we avoid it here\\r\\nvec3 computeNormalFast( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tfloat sampleAtPos = sceneMap(pos);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap(pos + point.xyy) - sampleAtPos,\\r\\n\\t\\t\\t\\t\\tsceneMap(pos + point.yxy) - sampleAtPos,\\r\\n\\t\\t\\t\\t\\tsceneMap(pos + point.yyx) - sampleAtPos));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Taken from a presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\\r\\nfloat ComputeAO( vec3 pos, vec3 normal ) {\\r\\n\\tfloat tStep = 0.0025;\\r\\n\\tfloat diff = 0.0;\\r\\n\\tfloat k = 34.0;\\r\\n\\tfor(float i = 1.0; i <= 5.0; i += 1.0) {\\r\\n\\t\\tvec3 sample = pos + (i * tStep) * normal;\\r\\n\\t\\tfloat dist = sceneMap( sample );\\r\\n\\t\\tdiff += pow(0.5, i) * ((i * tStep) - dist);\\r\\n\\t}\\r\\n\\treturn 1.0 - clamp(k * diff, 0.0, 0.9);\\r\\n}\\r\\n\\r\\n// Convert a fragment coordinate to normalized device coordinates\\r\\nvec2 FragCoordToNDC( vec4 fragCoord ) {\\r\\n\\treturn 2.0 * vec2(fragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t fragCoord.y / u_resolution.y) - 1.0;\\r\\n}\\r\\n\\r\\n// Return the direction of a ray cast through the given point in NDC\\r\\n// This function includes the implementation of the camera; changes to the camera should be made here\\r\\nvec3 Raycast( vec2 p_ndc, vec3 cameraPos ) {\\r\\n\\t\\r\\n\\tfloat len = 10.0;\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos); // Assume we are looking towards (0, 0, 0)\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = p_ndc.x * H + p_ndc.y * V;\\r\\n\\t\\r\\n\\t// Return the direction\\r\\n\\treturn normalize(point_World - cameraPos);\\r\\n}\\r\\n\\r\\n// Referencing the following report: http://celarek.at/wp/wp-content/uploads/2014/05/realTimeFractalsReport.pdf\\r\\nvec3 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\t// Basic Raymarching function: \\r\\n\\tfloat t = 0.01;\\r\\n\\tvec3 result = vec3(0.0);\\r\\n\\t\\r\\n\\tfor(int i = 1; i <= 250; i++) {\\r\\n\\t\\tfloat dist = sceneMap(origin + t * direction);\\r\\n\\t\\t\\r\\n\\t\\tif(abs(dist) < 0.0002) {\\r\\n\\t\\t\\tresult = vec3(t, float (i) / 1000.0, 1.0);\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tresult = vec3(T_MAX, float (i) / 1000.0, 0.0);\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn result;\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n\\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\\r\\n\\tvec2 point_NDC = FragCoordToNDC(gl_FragCoord);\\r\\n\\tvec3 direction = Raycast(point_NDC, cameraPos);\\r\\n\\t\\r\\n\\tvec3 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\tif(isect.z > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormalFast( isectPos );\\r\\n\\t\\tnormal = -normal;\\r\\n\\t\\t\\r\\n\\t\\t// Animated color using orbit traps: see the Mandelbulb SDF by IQ above\\r\\n\\t\\tvec3 trapColor;\\r\\n\\t\\t\\r\\n\\t\\tint sn = sceneNum();\\r\\n\\t\\tif(sn == 1)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(\\r\\n\\t\\t\\t\\tresColor.x-abs(sin((u_time) / 2.0 + isectPos.z) * 0.8), \\r\\n\\t\\t\\t\\tresColor.y-(cos((u_time) / 8.0 + isectPos.y) * 0.5), \\r\\n\\t\\t\\t\\tresColor.z+(cos((u_time) / 2.0 - isectPos.x) * 0.2));\\r\\n\\t\\t}\\r\\n\\t\\telse if(sn == 2)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(resColor) + vec3(0.4);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(0.0, resColor.y + 0.4, resColor.z + 0.4);\\r\\n\\t\\t}\\r\\n\\t\\t\\r\\n\\t\\ttrapColor.r *= 0.01;\\r\\n\\t\\t\\r\\n\\t\\t// Two methods to compute AO:\\r\\n\\t\\tfloat ao = ComputeAO(isectPos, normal);\\r\\n\\t\\t// float fakeAO = 1.0 - clamp(isect.y, 0.0, 0.9);\\r\\n\\t\\t\\r\\n\\t\\tgl_FragColor = ao * vec4(trapColor, 1);\\r\\n\\t\\t// gl_FragColor = fakeAO * vec4(trapColor, 1);\\r\\n\\t} else {\\r\\n\\t\\tgl_FragColor = vec4(backgroundColor(), 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/firstPass-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = \"/* \\r\\n\\tCode written by Joseph Klinger and Tabatha Hickman\\r\\n\\tUniversity of Pennsylvania\\r\\n\\tCIS 700 Instructor: Rachel Hwang\\r\\n\\tMay 2017\\r\\n*/\\r\\n\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 12.0\\r\\n#define MOTION_BLUR true\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform sampler2D u_firstPass;\\r\\nuniform sampler2D u_previousFrame;\\r\\n\\r\\n// The sole purpose of this pass is to compute motion blur between the current and previous frames\\r\\nvoid main() {\\r\\n\\t#ifdef MOTION_BLUR\\r\\n\\t\\tfor(float w = 0.0; w <= 1.0; w += 0.2) {\\r\\n\\t\\t\\tgl_FragColor += (1.0 - w) * texture2D(u_firstPass, f_uv) + w * texture2D(u_previousFrame, f_uv);\\r\\n\\t\\t}\\r\\n\\t\\tgl_FragColor /= 1.0 / 0.2; // divide by the number of samples (1 / stepSize)\\r\\n\\t#else\\r\\n\\t\\tgl_FragColor = texture2D(u_firstPass, f_uv);\\r\\n\\t#endif\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/secondPass-frag.glsl\n// module id = 16\n// module chunks = 0","module.exports = \"/* \\r\\n\\tCode written by Joseph Klinger and Tabatha Hickman\\r\\n\\tUniversity of Pennsylvania\\r\\n\\tCIS 700 Instructor: Rachel Hwang\\r\\n\\tMay 2017\\r\\n*/\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform sampler2D u_input;\\r\\n\\r\\nvoid main() {\\r\\n\\tgl_FragColor = texture2D(u_input, f_uv);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/thirdPass-frag.glsl\n// module id = 17\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 18\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 19\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap 40bbe202c4867be61fcb","webpack:///./src/main.js","webpack:///./~/dat-gui/index.js","webpack:///./~/dat-gui/vendor/dat.gui.js","webpack:///./~/dat-gui/vendor/dat.color.js","webpack:///./~/stats-js/build/stats.min.js","webpack:///./src/proxy_geometry.js","webpack:///./~/three/build/three.js","webpack:///./src/rayMarching.js","webpack:///./~/three-effectcomposer/index.js","webpack:///./~/three-copyshader/index.js","webpack:///./~/three-effectcomposer/lib/renderpass.js","webpack:///./~/three-effectcomposer/lib/shaderpass.js","webpack:///./~/three-effectcomposer/lib/maskpass.js","webpack:///./~/three-effectcomposer/lib/clearmaskpass.js","webpack:///./src/glsl/pass-vert.glsl","webpack:///./src/glsl/firstPass-frag.glsl","webpack:///./src/glsl/secondPass-frag.glsl","webpack:///./src/glsl/thirdPass-frag.glsl","webpack:///./index.html","webpack:///./~/three-orbit-controls/index.js"],"names":["require","THREE","OrbitControls","listener","AudioListener","sound","PositionalAudio","BoxGeometry","SphereGeometry","ConeGeometry","clock","Clock","window","addEventListener","stats","setMode","domElement","style","position","left","top","document","body","appendChild","scene","Scene","camera","PerspectiveCamera","innerWidth","innerHeight","renderer","WebGLRenderer","antialias","setPixelRatio","devicePixelRatio","setSize","setClearColor","controls","enableDamping","enableZoom","rotateSpeed","zoomSpeed","panSpeed","audioLoader","AudioLoader","load","buffer","setBuffer","setLoop","setVolume","play","aspect","updateProjectionMatrix","options","strategy","add","AxisHelper","DirectionalLight","proxyGeometry","boxMesh","Mesh","sphereMesh","coneMesh","set","group","lookAt","Vector3","target","rayMarcher","tick","update","begin","render","end","requestAnimationFrame","ProxyMaterial","MeshLambertMaterial","color","PROXY_BUFFER_SIZE","ProxyGeometry","bounds","Group","_buffer","Float32Array","mesh","children","length","computeBuffer","remove","t","i","child","x","y","z","geometry","RayMarcher","EffectComposer","target1","WebGLRenderTarget","composer1","shaderPass1","ShaderPass","uniforms","u_time","type","value","u_resolution","Vector2","u_fovy","fov","u_aspect","u_cwMat","u_ccwMat","u_northMat","u_southMat","u_westMat","u_eastMat","u_rotateX1","u_rotateY1","u_rotateZ1","u_rotateX2","u_rotateY2","u_rotateZ2","vertexShader","fragmentShader","composer2","shaderPass2","u_firstPass","u_previousFrame","renderToScreen","material","writeBuffer","texture","target3","composer3","shaderPass3","u_input","addPass","getElapsedTime","angle","cwMat","Matrix4","makeRotationY","ccwMat","northMat","makeRotationX","southMat","eastMat","makeRotationZ","westMat","rotateX1","rotateY1","rotateZ1","rotateX2","rotateY2","rotateZ2"],"mappings":"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AACA;;AAEA,W;;AAEA,cAAa;;AAEb;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAO;;AAEP;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA,6CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,MAAK;;AAEL;;;AAGA,kD;;AAEA;;AAEA,QAAO,0CAA0C;;AAEjD,0CAAyC,SAAS;AAClD;AACA;;AAEA,QAAO;;AAEP;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,SAAS;AAC5B;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,QAAO;AACP;;AAEA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,gCAA+B;AAC/B,QAAO;AACP;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA,YAAW;AACX;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,oBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sBAAqB,iCAAiC;AACtD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,SAAQ,OAAO;AACf;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB,gBAAe,UAAU;AACzB;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA,qEAAoE,iCAAiC;;AAErG;;AAEA;AACA;;;;AAIA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA,WAAU,iDAAiD,gBAAgB,uBAAuB,2BAA2B,qBAAqB,qBAAqB,GAAG,gBAAgB,yBAAyB,2BAA2B,gBAAgB,wBAAwB,yBAAyB,+BAA+B,GAAG,sBAAsB,0BAA0B,uBAAuB,2BAA2B,4BAA4B,gBAAgB,iBAAiB,uBAAuB,qBAAqB,kBAAkB,iBAAiB,GAAG;;;AAGlkB;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;;AAEA;AACA;AACA,4C;AACA,YAAW;AACX;AACA;;AAEA;;AAEA;;;AAGA;;AAEA;;AAEA;;AAEA,EAAC;AACD;AACA;;;AAGA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA,EAAC;;;AAGD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA,oDAAmD,EAAE;AACrD;;AAEA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;;;AAGA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB,cAAa,OAAO;AACpB;AACA,cAAa,QAAQ;AACrB,cAAa,YAAY;AACzB,cAAa,QAAQ;AACrB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;AACA;;AAEA,MAAK;;AAEL,sBAAqB;;AAErB;;AAEA;AACA;AACA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;;AAGA,QAAO;;;AAGP;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;AAGA;AACA;;AAEA;;AAEA,4CAA2C,mBAAmB;AAC9D,4DAA2D,kBAAkB,EAAE;AAC/E,sDAAqD,mBAAmB;AACxE,uDAAsD,mBAAmB;AACzE;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB,2BAA2B;AAChD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,sBAAqB,YAAY;AACjC,qBAAoB,MAAM;AAC1B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,yCAAwC;;AAExC;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;AACA;AACA,UAAS;;AAET;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,oBAAmB,UAAU;AAC7B,qBAAoB,MAAM;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;;AAEA,UAAS;;AAET;AACA,sBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA,sBAAqB,OAAO;AAC5B;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA,YAAW;;AAEX;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,UAAS;;AAET;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA,YAAW;;AAEX;AACA;AACA,YAAW;;AAEX;AACA;AACA;;;AAGA,UAAS;;AAET;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA,YAAW,wEAAwE;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe;;AAEf;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA,6BAA4B;AAC5B,QAAO;;AAEP;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,UAAS;;AAET;AACA;;AAEA,UAAS;;AAET;;AAEA;;AAEA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,QAAO;;AAEP;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;;AAEA;;AAEA;;AAEA,EAAC;AACD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,EAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;;AAGL;AACA;;AAEA;AACA;AACA;AACA,MAAK;;;AAGL;;AAEA;;AAEA;;;;AAIA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AA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AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;AAGA;;AAEA;;;AAGA,EAAC;AACD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;AACP;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA,EAAC;AACD;AACA,mB;;;;;;AClvBA;AACA,sBAAqB,mGAAmG,aAAa,2CAA2C,mBAAmB,SAAS,KAAK,4BAA4B,YAAY,gBAAgB,oCAAoC,WAAW,qCAAqC,gBAAgB,uBAAuB,iBAAiB,oCAAoC,eAAe,4BAA4B,uCAAuC,cAAc,iBAAiB;AAC1iB,mBAAkB,iBAAiB,oCAAoC,gBAAgB,mCAAmC,WAAW,YAAY,uBAAuB,qBAAqB,qBAAqB,EAAE,qCAAqC,2BAA2B,YAAY,WAAW,uBAAuB,iBAAiB,oCAAoC,UAAU,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EA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA,iBAAgB,YAAY;;AAE5B;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,qBAAoB,QAAQ;;AAE5B;;AAEA;;AAEA,OAAM;;AAEN;;AAEA,OAAM;;AAEN;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,uCAAsC,sBAAsB;;AAE5D;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4BAA2B;;;AAG3B;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAE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AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA,yBAAwB,kBAAkB;;AAE1C;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,2BAA0B;AAC1B;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;;AAEA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,KAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,4BAA2B;AAC3B,4BAA2B;AAC3B,4BAA2B;AAC3B;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA,KAAI;;AAEJ;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG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AiH,sDAAsD,oLAAoL,yJAAyJ,GAAG;;AAEjjB,oJAAmJ,sDAAsD,mMAAmM,6PAA6P,4TAA4T,WAAW;;AAEh9B,0CAAyC,wBAAwB,+QAA+Q,4EAA4E,iDAAiD,0KAA0K,yDAAyD,6IAA6I;;AAE7zB,wCAAuC,sBAAsB,0MAA0M,wKAAwK,mCAAmC,yKAAyK;;AAE3nB,2CAA0C,yKAAyK,8EAA8E,GAAG;;AAEpS,oEAAmE,wHAAwH;;AAE3L;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,MAAK;;AAEL;AACA;;AAEA;AACA;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;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,mBAAkB,OAAO;;AAEzB;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA,+CAA8C;;AAE9C;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;A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AEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,KAAI;;AAEJ;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA,MAAK;;AAEL;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;AACA;;AAEA,MAAK;;AAEL;AACA;;AAEA;;AAEA,KAAI;;A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AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA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A;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,KAAI;;AAEJ;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAE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;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,gBAAe,sBAAsB;;AAErC,iBAAgB,qBAAqB;;AAErC;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA,gBAAe,qBAAqB;;AAEpC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,sBAAsB;;AAEpC,gBAAe,qBAAqB;;AAEpC;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;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;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,sBAAqB,eAAe;;AAEpC;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,eAAc,eAAe;;AAE7B;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;;AAEA,0CAAyC,OAAO;;AAEhD;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,2BAA2B;;AAE9C;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA,2BAA0B;;AAE1B;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;AACrC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA,mBAAkB;;AAElB;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,sCAAqC;;AAErC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;AAEA,wCAAuC,SAAS;;AAEhD;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,oBAAmB,sBAAsB;;AAEzC;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,OAAM;;AAEN;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;AACA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;;AAEA;AACA;;AAEA;;AAEA,KAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;;AAEA;AACA;;AAEA,KAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;AAEA,GAAE;;AAEF;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,IAAG;AACH;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA,IAAG;;AAEH;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A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","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 40bbe202c4867be61fcb","require('file-loader?name=[name].[ext]!../index.html');\r\n\r\nconst THREE = require('three');\r\nconst OrbitControls = require('three-orbit-controls')(THREE)\r\n\r\nimport DAT from 'dat-gui'\r\nimport Stats from 'stats-js'\r\nimport ProxyGeometry, {ProxyMaterial} from './proxy_geometry'\r\nimport RayMarcher from './rayMarching'\r\n\r\n//Audio and Audio Analysis variables\r\n \r\n//Create an AudioListener and add it to the camera\r\nvar listener = new THREE.AudioListener();\r\n \r\n// create a global audio source\r\nvar sound = new THREE.PositionalAudio( listener );\r\n\r\nvar BoxGeometry = new THREE.BoxGeometry(1, 1, 1);\r\nvar SphereGeometry = new THREE.SphereGeometry(1, 32, 32);\r\nvar ConeGeometry = new THREE.ConeGeometry(1, 1);\r\n\r\nvar clock = new THREE.Clock();\r\n\r\nwindow.addEventListener('load', function() {\r\n var stats = new Stats();\r\n stats.setMode(1);\r\n stats.domElement.style.position = 'absolute';\r\n stats.domElement.style.left = '0px';\r\n stats.domElement.style.top = '0px';\r\n document.body.appendChild(stats.domElement);\r\n\r\n var scene = new THREE.Scene();\r\n var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );\r\n var renderer = new THREE.WebGLRenderer( { antialias: true } );\r\n renderer.setPixelRatio(window.devicePixelRatio);\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n renderer.setClearColor(0x999999, 1.0);\r\n document.body.appendChild(renderer.domElement);\r\n\r\n var controls = new OrbitControls(camera, renderer.domElement);\r\n controls.enableDamping = true;\r\n controls.enableZoom = true;\r\n controls.rotateSpeed = 0.3;\r\n controls.zoomSpeed = 1.0;\r\n controls.panSpeed = 2.0;\r\n\r\n\r\n var audioLoader = new THREE.AudioLoader();\r\n \r\n //Load a sound and set it as the Audio object's buffer\r\n audioLoader.load( 'Dubstep_Sub-Mix_2016.mp3', function( buffer ) {\r\n sound.setBuffer( buffer );\r\n sound.setLoop(true);\r\n sound.setVolume(1.0);\r\n sound.play();\r\n }); \r\n\r\n window.addEventListener('resize', function() {\r\n camera.aspect = window.innerWidth / window.innerHeight;\r\n camera.updateProjectionMatrix();\r\n renderer.setSize(window.innerWidth, window.innerHeight);\r\n });\r\n\r\n // var gui = new DAT.GUI();\r\n\r\n var options = {\r\n strategy: 'Ray Marching'\r\n }\r\n\r\n // gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']);\r\n\r\n scene.add(new THREE.AxisHelper(20));\r\n scene.add(new THREE.DirectionalLight(0xffffff, 1));\r\n\r\n var proxyGeometry = new ProxyGeometry();\r\n\r\n var boxMesh = new THREE.Mesh(BoxGeometry, ProxyMaterial);\r\n var sphereMesh = new THREE.Mesh(SphereGeometry, ProxyMaterial);\r\n var coneMesh = new THREE.Mesh(ConeGeometry, ProxyMaterial);\r\n \r\n boxMesh.position.set(-3, 0, 0);\r\n coneMesh.position.set(3, 0, 0);\r\n\r\n proxyGeometry.add(boxMesh);\r\n proxyGeometry.add(sphereMesh);\r\n proxyGeometry.add(coneMesh);\r\n\r\n scene.add(proxyGeometry.group);\r\n\r\n camera.position.set(5, 10, 15);\r\n camera.lookAt(new THREE.Vector3(0,0,0));\r\n controls.target.set(0,0,0);\r\n \r\n var rayMarcher = new RayMarcher(renderer, scene, camera);\r\n\r\n (function tick() {\r\n controls.update();\r\n stats.begin();\r\n proxyGeometry.update();\r\n if (options.strategy === 'Proxy Geometry') {\r\n renderer.render(scene, camera);\r\n } else if (options.strategy === 'Ray Marching') {\r\n rayMarcher.render(proxyGeometry.buffer, clock);\r\n }\r\n stats.end();\r\n requestAnimationFrame(tick);\r\n })();\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/index.js\n// module id = 1\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n return {\n load: function (url, doc) {\n doc = doc || document;\n var link = doc.createElement('link');\n link.type = 'text/css';\n link.rel = 'stylesheet';\n link.href = url;\n doc.getElementsByTagName('head')[0].appendChild(link);\n },\n inject: function(css, doc) {\n doc = doc || document;\n var injected = document.createElement('style');\n injected.type = 'text/css';\n injected.innerHTML = css;\n doc.getElementsByTagName('head')[0].appendChild(injected);\n }\n }\n})();\n\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n /**\n * @class An \"abstract\" class that represents a given property of an object.\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var Controller = function(object, property) {\n\n this.initialValue = object[property];\n\n /**\n * Those who extend this class will put their DOM elements in here.\n * @type {DOMElement}\n */\n this.domElement = document.createElement('div');\n\n /**\n * The object to manipulate\n * @type {Object}\n */\n this.object = object;\n\n /**\n * The name of the property to manipulate\n * @type {String}\n */\n this.property = property;\n\n /**\n * The function to be called on change.\n * @type {Function}\n * @ignore\n */\n this.__onChange = undefined;\n\n /**\n * The function to be called on finishing change.\n * @type {Function}\n * @ignore\n */\n this.__onFinishChange = undefined;\n\n };\n\n common.extend(\n\n Controller.prototype,\n\n /** @lends dat.controllers.Controller.prototype */\n {\n\n /**\n * Specify that a function fire every time someone changes the value with\n * this Controller.\n *\n * @param {Function} fnc This function will be called whenever the value\n * is modified via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onChange: function(fnc) {\n this.__onChange = fnc;\n return this;\n },\n\n /**\n * Specify that a function fire every time someone \"finishes\" changing\n * the value wih this Controller. Useful for values that change\n * incrementally like numbers or strings.\n *\n * @param {Function} fnc This function will be called whenever\n * someone \"finishes\" changing the value via this Controller.\n * @returns {dat.controllers.Controller} this\n */\n onFinishChange: function(fnc) {\n this.__onFinishChange = fnc;\n return this;\n },\n\n /**\n * Change the value of object[property]\n *\n * @param {Object} newValue The new value of object[property]\n */\n setValue: function(newValue) {\n this.object[this.property] = newValue;\n if (this.__onChange) {\n this.__onChange.call(this, newValue);\n }\n this.updateDisplay();\n return this;\n },\n\n /**\n * Gets the value of object[property]\n *\n * @returns {Object} The current value of object[property]\n */\n getValue: function() {\n return this.object[this.property];\n },\n\n /**\n * Refreshes the visual display of a Controller in order to keep sync\n * with the object's current value.\n * @returns {dat.controllers.Controller} this\n */\n updateDisplay: function() {\n return this;\n },\n\n /**\n * @returns {Boolean} true if the value has deviated from initialValue\n */\n isModified: function() {\n return this.initialValue !== this.getValue()\n }\n\n }\n\n );\n\n return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n var EVENT_MAP = {\n 'HTMLEvents': ['change'],\n 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n 'KeyboardEvents': ['keydown']\n };\n\n var EVENT_MAP_INV = {};\n common.each(EVENT_MAP, function(v, k) {\n common.each(v, function(e) {\n EVENT_MAP_INV[e] = k;\n });\n });\n\n var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n function cssValueToPixels(val) {\n\n if (val === '0' || common.isUndefined(val)) return 0;\n\n var match = val.match(CSS_VALUE_PIXELS);\n\n if (!common.isNull(match)) {\n return parseFloat(match[1]);\n }\n\n // TODO ...ems? %?\n\n return 0;\n\n }\n\n /**\n * @namespace\n * @member dat.dom\n */\n var dom = {\n\n /**\n * \n * @param elem\n * @param selectable\n */\n makeSelectable: function(elem, selectable) {\n\n if (elem === undefined || elem.style === undefined) return;\n\n elem.onselectstart = selectable ? function() {\n return false;\n } : function() {\n };\n\n elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n elem.unselectable = selectable ? 'on' : 'off';\n\n },\n\n /**\n *\n * @param elem\n * @param horizontal\n * @param vertical\n */\n makeFullscreen: function(elem, horizontal, vertical) {\n\n if (common.isUndefined(horizontal)) horizontal = true;\n if (common.isUndefined(vertical)) vertical = true;\n\n elem.style.position = 'absolute';\n\n if (horizontal) {\n elem.style.left = 0;\n elem.style.right = 0;\n }\n if (vertical) {\n elem.style.top = 0;\n elem.style.bottom = 0;\n }\n\n },\n\n /**\n *\n * @param elem\n * @param eventType\n * @param params\n */\n fakeEvent: function(elem, eventType, params, aux) {\n params = params || {};\n var className = EVENT_MAP_INV[eventType];\n if (!className) {\n throw new Error('Event type ' + eventType + ' not supported.');\n }\n var evt = document.createEvent(className);\n switch (className) {\n case 'MouseEvents':\n var clientX = params.x || params.clientX || 0;\n var clientY = params.y || params.clientY || 0;\n evt.initMouseEvent(eventType, params.bubbles || false,\n params.cancelable || true, window, params.clickCount || 1,\n 0, //screen X\n 0, //screen Y\n clientX, //client X\n clientY, //client Y\n false, false, false, false, 0, null);\n break;\n case 'KeyboardEvents':\n var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n common.defaults(params, {\n cancelable: true,\n ctrlKey: false,\n altKey: false,\n shiftKey: false,\n metaKey: false,\n keyCode: undefined,\n charCode: undefined\n });\n init(eventType, params.bubbles || false,\n params.cancelable, window,\n params.ctrlKey, params.altKey,\n params.shiftKey, params.metaKey,\n params.keyCode, params.charCode);\n break;\n default:\n evt.initEvent(eventType, params.bubbles || false,\n params.cancelable || true);\n break;\n }\n common.defaults(evt, aux);\n elem.dispatchEvent(evt);\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n bind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.addEventListener)\n elem.addEventListener(event, func, bool);\n else if (elem.attachEvent)\n elem.attachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param event\n * @param func\n * @param bool\n */\n unbind: function(elem, event, func, bool) {\n bool = bool || false;\n if (elem.removeEventListener)\n elem.removeEventListener(event, func, bool);\n else if (elem.detachEvent)\n elem.detachEvent('on' + event, func);\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n addClass: function(elem, className) {\n if (elem.className === undefined) {\n elem.className = className;\n } else if (elem.className !== className) {\n var classes = elem.className.split(/ +/);\n if (classes.indexOf(className) == -1) {\n classes.push(className);\n elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n }\n }\n return dom;\n },\n\n /**\n *\n * @param elem\n * @param className\n */\n removeClass: function(elem, className) {\n if (className) {\n if (elem.className === undefined) {\n // elem.className = className;\n } else if (elem.className === className) {\n elem.removeAttribute('class');\n } else {\n var classes = elem.className.split(/ +/);\n var index = classes.indexOf(className);\n if (index != -1) {\n classes.splice(index, 1);\n elem.className = classes.join(' ');\n }\n }\n } else {\n elem.className = undefined;\n }\n return dom;\n },\n\n hasClass: function(elem, className) {\n return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n },\n\n /**\n *\n * @param elem\n */\n getWidth: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-left-width']) +\n cssValueToPixels(style['border-right-width']) +\n cssValueToPixels(style['padding-left']) +\n cssValueToPixels(style['padding-right']) +\n cssValueToPixels(style['width']);\n },\n\n /**\n *\n * @param elem\n */\n getHeight: function(elem) {\n\n var style = getComputedStyle(elem);\n\n return cssValueToPixels(style['border-top-width']) +\n cssValueToPixels(style['border-bottom-width']) +\n cssValueToPixels(style['padding-top']) +\n cssValueToPixels(style['padding-bottom']) +\n cssValueToPixels(style['height']);\n },\n\n /**\n *\n * @param elem\n */\n getOffset: function(elem) {\n var offset = {left: 0, top:0};\n if (elem.offsetParent) {\n do {\n offset.left += elem.offsetLeft;\n offset.top += elem.offsetTop;\n } while (elem = elem.offsetParent);\n }\n return offset;\n },\n\n // http://stackoverflow.com/posts/2684561/revisions\n /**\n * \n * @param elem\n */\n isActive: function(elem) {\n return elem === document.activeElement && ( elem.type || elem.href );\n }\n\n };\n\n return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a select input to alter the property of an object, using a\n * list of accepted values.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object|string[]} options A map of labels to acceptable values, or\n * a list of acceptable string values.\n *\n * @member dat.controllers\n */\n var OptionController = function(object, property, options) {\n\n OptionController.superclass.call(this, object, property);\n\n var _this = this;\n\n /**\n * The drop down menu\n * @ignore\n */\n this.__select = document.createElement('select');\n\n if (common.isArray(options)) {\n var map = {};\n common.each(options, function(element) {\n map[element] = element;\n });\n options = map;\n }\n\n common.each(options, function(value, key) {\n\n var opt = document.createElement('option');\n opt.innerHTML = key;\n opt.setAttribute('value', value);\n _this.__select.appendChild(opt);\n\n });\n\n // Acknowledge original value\n this.updateDisplay();\n\n dom.bind(this.__select, 'change', function() {\n var desiredValue = this.options[this.selectedIndex].value;\n _this.setValue(desiredValue);\n });\n\n this.domElement.appendChild(this.__select);\n\n };\n\n OptionController.superclass = Controller;\n\n common.extend(\n\n OptionController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n return toReturn;\n },\n\n updateDisplay: function() {\n this.__select.value = this.getValue();\n return OptionController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n /**\n * @class Represents a given property of an object that is a number.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberController = function(object, property, params) {\n\n NumberController.superclass.call(this, object, property);\n\n params = params || {};\n\n this.__min = params.min;\n this.__max = params.max;\n this.__step = params.step;\n\n if (common.isUndefined(this.__step)) {\n\n if (this.initialValue == 0) {\n this.__impliedStep = 1; // What are we, psychics?\n } else {\n // Hey Doug, check this out.\n this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n }\n\n } else {\n\n this.__impliedStep = this.__step;\n\n }\n\n this.__precision = numDecimals(this.__impliedStep);\n\n\n };\n\n NumberController.superclass = Controller;\n\n common.extend(\n\n NumberController.prototype,\n Controller.prototype,\n\n /** @lends dat.controllers.NumberController.prototype */\n {\n\n setValue: function(v) {\n\n if (this.__min !== undefined && v < this.__min) {\n v = this.__min;\n } else if (this.__max !== undefined && v > this.__max) {\n v = this.__max;\n }\n\n if (this.__step !== undefined && v % this.__step != 0) {\n v = Math.round(v / this.__step) * this.__step;\n }\n\n return NumberController.superclass.prototype.setValue.call(this, v);\n\n },\n\n /**\n * Specify a minimum value for object[property].\n *\n * @param {Number} minValue The minimum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n min: function(v) {\n this.__min = v;\n return this;\n },\n\n /**\n * Specify a maximum value for object[property].\n *\n * @param {Number} maxValue The maximum value for\n * object[property]\n * @returns {dat.controllers.NumberController} this\n */\n max: function(v) {\n this.__max = v;\n return this;\n },\n\n /**\n * Specify a step value that dat.controllers.NumberController\n * increments by.\n *\n * @param {Number} stepValue The step value for\n * dat.controllers.NumberController\n * @default if minimum and maximum specified increment is 1% of the\n * difference otherwise stepValue is 1\n * @returns {dat.controllers.NumberController} this\n */\n step: function(v) {\n this.__step = v;\n return this;\n }\n\n }\n\n );\n\n function numDecimals(x) {\n x = x.toString();\n if (x.indexOf('.') > -1) {\n return x.length - x.indexOf('.') - 1;\n } else {\n return 0;\n }\n }\n\n return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n /**\n * @class Represents a given property of an object that is a number and\n * provides an input element with which to manipulate it.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Object} [params] Optional parameters\n * @param {Number} [params.min] Minimum allowed value\n * @param {Number} [params.max] Maximum allowed value\n * @param {Number} [params.step] Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerBox = function(object, property, params) {\n\n this.__truncationSuspended = false;\n\n NumberControllerBox.superclass.call(this, object, property, params);\n\n var _this = this;\n\n /**\n * {Number} Previous mouse y position\n * @ignore\n */\n var prev_y;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n // Makes it so manually specified values are not truncated.\n\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'mousedown', onMouseDown);\n dom.bind(this.__input, 'keydown', function(e) {\n\n // When pressing entire, you can be as precise as you want.\n if (e.keyCode === 13) {\n _this.__truncationSuspended = true;\n this.blur();\n _this.__truncationSuspended = false;\n }\n\n });\n\n function onChange() {\n var attempted = parseFloat(_this.__input.value);\n if (!common.isNaN(attempted)) _this.setValue(attempted);\n }\n\n function onBlur() {\n onChange();\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n function onMouseDown(e) {\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n prev_y = e.clientY;\n }\n\n function onMouseDrag(e) {\n\n var diff = prev_y - e.clientY;\n _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n prev_y = e.clientY;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n NumberControllerBox.superclass = NumberController;\n\n common.extend(\n\n NumberControllerBox.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n\n this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n function roundToDecimal(value, decimals) {\n var tenTo = Math.pow(10, decimals);\n return Math.round(value * tenTo) / tenTo;\n }\n\n return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n /**\n * @class Represents a given property of an object that is a number, contains\n * a minimum and maximum, and provides a slider element with which to\n * manipulate it. It should be noted that the slider element is made up of\n * <div> tags, not the html5\n * <slider> element.\n *\n * @extends dat.controllers.Controller\n * @extends dat.controllers.NumberController\n * \n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n * @param {Number} minValue Minimum allowed value\n * @param {Number} maxValue Maximum allowed value\n * @param {Number} stepValue Increment by which to change value\n *\n * @member dat.controllers\n */\n var NumberControllerSlider = function(object, property, min, max, step) {\n\n NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n var _this = this;\n\n this.__background = document.createElement('div');\n this.__foreground = document.createElement('div');\n \n\n\n dom.bind(this.__background, 'mousedown', onMouseDown);\n \n dom.addClass(this.__background, 'slider');\n dom.addClass(this.__foreground, 'slider-fg');\n\n function onMouseDown(e) {\n\n dom.bind(window, 'mousemove', onMouseDrag);\n dom.bind(window, 'mouseup', onMouseUp);\n\n onMouseDrag(e);\n }\n\n function onMouseDrag(e) {\n\n e.preventDefault();\n\n var offset = dom.getOffset(_this.__background);\n var width = dom.getWidth(_this.__background);\n \n _this.setValue(\n map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n );\n\n return false;\n\n }\n\n function onMouseUp() {\n dom.unbind(window, 'mousemove', onMouseDrag);\n dom.unbind(window, 'mouseup', onMouseUp);\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.__background.appendChild(this.__foreground);\n this.domElement.appendChild(this.__background);\n\n };\n\n NumberControllerSlider.superclass = NumberController;\n\n /**\n * Injects default stylesheet for slider elements.\n */\n NumberControllerSlider.useDefaultStyles = function() {\n css.inject(styleSheet);\n };\n\n common.extend(\n\n NumberControllerSlider.prototype,\n NumberController.prototype,\n\n {\n\n updateDisplay: function() {\n var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n this.__foreground.style.width = pct*100+'%';\n return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n\n\n );\n\n function map(v, i1, i2, o1, o2) {\n return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n }\n\n return NumberControllerSlider;\n \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".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}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a GUI interface to fire a specified method, a property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var FunctionController = function(object, property, text) {\n\n FunctionController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__button = document.createElement('div');\n this.__button.innerHTML = text === undefined ? 'Fire' : text;\n dom.bind(this.__button, 'click', function(e) {\n e.preventDefault();\n _this.fire();\n return false;\n });\n\n dom.addClass(this.__button, 'button');\n\n this.domElement.appendChild(this.__button);\n\n\n };\n\n FunctionController.superclass = Controller;\n\n common.extend(\n\n FunctionController.prototype,\n Controller.prototype,\n {\n \n fire: function() {\n if (this.__onChange) {\n this.__onChange.call(this);\n }\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.getValue().call(this.object);\n }\n }\n\n );\n\n return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a checkbox input to alter the boolean property of an object.\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var BooleanController = function(object, property) {\n\n BooleanController.superclass.call(this, object, property);\n\n var _this = this;\n this.__prev = this.getValue();\n\n this.__checkbox = document.createElement('input');\n this.__checkbox.setAttribute('type', 'checkbox');\n\n\n dom.bind(this.__checkbox, 'change', onChange, false);\n\n this.domElement.appendChild(this.__checkbox);\n\n // Match original value\n this.updateDisplay();\n\n function onChange() {\n _this.setValue(!_this.__prev);\n }\n\n };\n\n BooleanController.superclass = Controller;\n\n common.extend(\n\n BooleanController.prototype,\n Controller.prototype,\n\n {\n\n setValue: function(v) {\n var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n if (this.__onFinishChange) {\n this.__onFinishChange.call(this, this.getValue());\n }\n this.__prev = this.getValue();\n return toReturn;\n },\n\n updateDisplay: function() {\n \n if (this.getValue() === true) {\n this.__checkbox.setAttribute('checked', 'checked');\n this.__checkbox.checked = true; \n } else {\n this.__checkbox.checked = false;\n }\n\n return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n }\n\n\n }\n\n );\n\n return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n css.inject(styleSheet);\n\n /** Outer-most className for GUI's */\n var CSS_NAMESPACE = 'dg';\n\n var HIDE_KEY_CODE = 72;\n\n /** The only value shared between the JS and SCSS. Use caution. */\n var CLOSE_BUTTON_HEIGHT = 20;\n\n var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n var SUPPORTS_LOCAL_STORAGE = (function() {\n try {\n return 'localStorage' in window && window['localStorage'] !== null;\n } catch (e) {\n return false;\n }\n })();\n\n var SAVE_DIALOGUE;\n\n /** Have we yet to create an autoPlace GUI? */\n var auto_place_virgin = true;\n\n /** Fixed position div that auto place GUI's go inside */\n var auto_place_container;\n\n /** Are we hiding the GUI's ? */\n var hide = false;\n\n /** GUI's which should be hidden */\n var hideable_guis = [];\n\n /**\n * A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n * @class\n *\n * @member dat.gui\n *\n * @param {Object} [params]\n * @param {String} [params.name] The name of this GUI.\n * @param {Object} [params.load] JSON object representing the saved state of\n * this GUI.\n * @param {Boolean} [params.auto=true]\n * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.closed] If true, starts closed\n */\n var GUI = function(params) {\n\n var _this = this;\n\n /**\n * Outermost DOM Element\n * @type DOMElement\n */\n this.domElement = document.createElement('div');\n this.__ul = document.createElement('ul');\n this.domElement.appendChild(this.__ul);\n\n dom.addClass(this.domElement, CSS_NAMESPACE);\n\n /**\n * Nested GUI's by name\n * @ignore\n */\n this.__folders = {};\n\n this.__controllers = [];\n\n /**\n * List of objects I'm remembering for save, only used in top level GUI\n * @ignore\n */\n this.__rememberedObjects = [];\n\n /**\n * Maps the index of remembered objects to a map of controllers, only used\n * in top level GUI.\n *\n * @private\n * @ignore\n *\n * @example\n * [\n * {\n * propertyName: Controller,\n * anotherPropertyName: Controller\n * },\n * {\n * propertyName: Controller\n * }\n * ]\n */\n this.__rememberedObjectIndecesToControllers = [];\n\n this.__listening = [];\n\n params = params || {};\n\n // Default parameters\n params = common.defaults(params, {\n autoPlace: true,\n width: GUI.DEFAULT_WIDTH\n });\n\n params = common.defaults(params, {\n resizable: params.autoPlace,\n hideable: params.autoPlace\n });\n\n\n if (!common.isUndefined(params.load)) {\n\n // Explicit preset\n if (params.preset) params.load.preset = params.preset;\n\n } else {\n\n params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n }\n\n if (common.isUndefined(params.parent) && params.hideable) {\n hideable_guis.push(this);\n }\n\n // Only root level GUI's are resizable.\n params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n if (params.autoPlace && common.isUndefined(params.scrollable)) {\n params.scrollable = true;\n }\n// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n // Not part of params because I don't want people passing this in via\n // constructor. Should be a 'remembered' value.\n var use_local_storage =\n SUPPORTS_LOCAL_STORAGE &&\n localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n Object.defineProperties(this,\n\n /** @lends dat.gui.GUI.prototype */\n {\n\n /**\n * The parent GUI\n * @type dat.gui.GUI\n */\n parent: {\n get: function() {\n return params.parent;\n }\n },\n\n scrollable: {\n get: function() {\n return params.scrollable;\n }\n },\n\n /**\n * Handles GUI's element placement for you\n * @type Boolean\n */\n autoPlace: {\n get: function() {\n return params.autoPlace;\n }\n },\n\n /**\n * The identifier for a set of saved values\n * @type String\n */\n preset: {\n\n get: function() {\n if (_this.parent) {\n return _this.getRoot().preset;\n } else {\n return params.load.preset;\n }\n },\n\n set: function(v) {\n if (_this.parent) {\n _this.getRoot().preset = v;\n } else {\n params.load.preset = v;\n }\n setPresetSelectIndex(this);\n _this.revert();\n }\n\n },\n\n /**\n * The width of GUI element\n * @type Number\n */\n width: {\n get: function() {\n return params.width;\n },\n set: function(v) {\n params.width = v;\n setWidth(_this, v);\n }\n },\n\n /**\n * The name of GUI. Used for folders. i.e\n * a folder's name\n * @type String\n */\n name: {\n get: function() {\n return params.name;\n },\n set: function(v) {\n // TODO Check for collisions among sibling folders\n params.name = v;\n if (title_row_name) {\n title_row_name.innerHTML = params.name;\n }\n }\n },\n\n /**\n * Whether the GUI is collapsed or not\n * @type Boolean\n */\n closed: {\n get: function() {\n return params.closed;\n },\n set: function(v) {\n params.closed = v;\n if (params.closed) {\n dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n } else {\n dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n }\n // For browsers that aren't going to respect the CSS transition,\n // Lets just check our height against the window height right off\n // the bat.\n this.onResize();\n\n if (_this.__closeButton) {\n _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n }\n }\n },\n\n /**\n * Contains all presets\n * @type Object\n */\n load: {\n get: function() {\n return params.load;\n }\n },\n\n /**\n * Determines whether or not to use localStorage as the means for\n * remembering\n * @type Boolean\n */\n useLocalStorage: {\n\n get: function() {\n return use_local_storage;\n },\n set: function(bool) {\n if (SUPPORTS_LOCAL_STORAGE) {\n use_local_storage = bool;\n if (bool) {\n dom.bind(window, 'unload', saveToLocalStorage);\n } else {\n dom.unbind(window, 'unload', saveToLocalStorage);\n }\n localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n }\n }\n\n }\n\n });\n\n // Are we a root level GUI?\n if (common.isUndefined(params.parent)) {\n\n params.closed = false;\n\n dom.addClass(this.domElement, GUI.CLASS_MAIN);\n dom.makeSelectable(this.domElement, false);\n\n // Are we supposed to be loading locally?\n if (SUPPORTS_LOCAL_STORAGE) {\n\n if (use_local_storage) {\n\n _this.useLocalStorage = true;\n\n var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n if (saved_gui) {\n params.load = JSON.parse(saved_gui);\n }\n\n }\n\n }\n\n this.__closeButton = document.createElement('div');\n this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n this.domElement.appendChild(this.__closeButton);\n\n dom.bind(this.__closeButton, 'click', function() {\n\n _this.closed = !_this.closed;\n\n\n });\n\n\n // Oh, you're a nested GUI!\n } else {\n\n if (params.closed === undefined) {\n params.closed = true;\n }\n\n var title_row_name = document.createTextNode(params.name);\n dom.addClass(title_row_name, 'controller-name');\n\n var title_row = addRow(_this, title_row_name);\n\n var on_click_title = function(e) {\n e.preventDefault();\n _this.closed = !_this.closed;\n return false;\n };\n\n dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n dom.addClass(title_row, 'title');\n dom.bind(title_row, 'click', on_click_title);\n\n if (!params.closed) {\n this.closed = false;\n }\n\n }\n\n if (params.autoPlace) {\n\n if (common.isUndefined(params.parent)) {\n\n if (auto_place_virgin) {\n auto_place_container = document.createElement('div');\n dom.addClass(auto_place_container, CSS_NAMESPACE);\n dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n document.body.appendChild(auto_place_container);\n auto_place_virgin = false;\n }\n\n // Put it in the dom for you.\n auto_place_container.appendChild(this.domElement);\n\n // Apply the auto styles\n dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n }\n\n\n // Make it not elastic.\n if (!this.parent) setWidth(_this, params.width);\n\n }\n\n dom.bind(window, 'resize', function() { _this.onResize() });\n dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n this.onResize();\n\n\n if (params.resizable) {\n addResizeHandle(this);\n }\n\n function saveToLocalStorage() {\n localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n }\n\n var root = _this.getRoot();\n function resetWidth() {\n var root = _this.getRoot();\n root.width += 1;\n common.defer(function() {\n root.width -= 1;\n });\n }\n\n if (!params.parent) {\n resetWidth();\n }\n\n };\n\n GUI.toggleHide = function() {\n\n hide = !hide;\n common.each(hideable_guis, function(gui) {\n gui.domElement.style.zIndex = hide ? -999 : 999;\n gui.domElement.style.opacity = hide ? 0 : 1;\n });\n };\n\n GUI.CLASS_AUTO_PLACE = 'a';\n GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n GUI.CLASS_MAIN = 'main';\n GUI.CLASS_CONTROLLER_ROW = 'cr';\n GUI.CLASS_TOO_TALL = 'taller-than-window';\n GUI.CLASS_CLOSED = 'closed';\n GUI.CLASS_CLOSE_BUTTON = 'close-button';\n GUI.CLASS_DRAG = 'drag';\n\n GUI.DEFAULT_WIDTH = 245;\n GUI.TEXT_CLOSED = 'Close Controls';\n GUI.TEXT_OPEN = 'Open Controls';\n\n dom.bind(window, 'keydown', function(e) {\n\n if (document.activeElement.type !== 'text' &&\n (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n GUI.toggleHide();\n }\n\n }, false);\n\n common.extend(\n\n GUI.prototype,\n\n /** @lends dat.gui.GUI */\n {\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.Controller} The new controller that was added.\n * @instance\n */\n add: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n factoryArgs: Array.prototype.slice.call(arguments, 2)\n }\n );\n\n },\n\n /**\n * @param object\n * @param property\n * @returns {dat.controllers.ColorController} The new controller that was added.\n * @instance\n */\n addColor: function(object, property) {\n\n return add(\n this,\n object,\n property,\n {\n color: true\n }\n );\n\n },\n\n /**\n * @param controller\n * @instance\n */\n remove: function(controller) {\n\n // TODO listening?\n this.__ul.removeChild(controller.__li);\n this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n var _this = this;\n common.defer(function() {\n _this.onResize();\n });\n\n },\n\n destroy: function() {\n\n if (this.autoPlace) {\n auto_place_container.removeChild(this.domElement);\n }\n\n },\n\n /**\n * @param name\n * @returns {dat.gui.GUI} The new folder.\n * @throws {Error} if this GUI already has a folder by the specified\n * name\n * @instance\n */\n addFolder: function(name) {\n\n // We have to prevent collisions on names in order to have a key\n // by which to remember saved values\n if (this.__folders[name] !== undefined) {\n throw new Error('You already have a folder in this GUI by the' +\n ' name \"' + name + '\"');\n }\n\n var new_gui_params = { name: name, parent: this };\n\n // We need to pass down the autoPlace trait so that we can\n // attach event listeners to open/close folder actions to\n // ensure that a scrollbar appears if the window is too short.\n new_gui_params.autoPlace = this.autoPlace;\n\n // Do we have saved appearance data for this folder?\n\n if (this.load && // Anything loaded?\n this.load.folders && // Was my parent a dead-end?\n this.load.folders[name]) { // Did daddy remember me?\n\n // Start me closed if I was closed\n new_gui_params.closed = this.load.folders[name].closed;\n\n // Pass down the loaded data\n new_gui_params.load = this.load.folders[name];\n\n }\n\n var gui = new GUI(new_gui_params);\n this.__folders[name] = gui;\n\n var li = addRow(this, gui.domElement);\n dom.addClass(li, 'folder');\n return gui;\n\n },\n\n open: function() {\n this.closed = false;\n },\n\n close: function() {\n this.closed = true;\n },\n\n onResize: function() {\n\n var root = this.getRoot();\n\n if (root.scrollable) {\n\n var top = dom.getOffset(root.__ul).top;\n var h = 0;\n\n common.each(root.__ul.childNodes, function(node) {\n if (! (root.autoPlace && node === root.__save_row))\n h += dom.getHeight(node);\n });\n\n if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n } else {\n dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n root.__ul.style.height = 'auto';\n }\n\n }\n\n if (root.__resize_handle) {\n common.defer(function() {\n root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n });\n }\n\n if (root.__closeButton) {\n root.__closeButton.style.width = root.width + 'px';\n }\n\n },\n\n /**\n * Mark objects for saving. The order of these objects cannot change as\n * the GUI grows. When remembering new objects, append them to the end\n * of the list.\n *\n * @param {Object...} objects\n * @throws {Error} if not called on a top level GUI.\n * @instance\n */\n remember: function() {\n\n if (common.isUndefined(SAVE_DIALOGUE)) {\n SAVE_DIALOGUE = new CenteredDiv();\n SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n }\n\n if (this.parent) {\n throw new Error(\"You can only call remember on a top level GUI.\");\n }\n\n var _this = this;\n\n common.each(Array.prototype.slice.call(arguments), function(object) {\n if (_this.__rememberedObjects.length == 0) {\n addSaveMenu(_this);\n }\n if (_this.__rememberedObjects.indexOf(object) == -1) {\n _this.__rememberedObjects.push(object);\n }\n });\n\n if (this.autoPlace) {\n // Set save row width\n setWidth(this, this.width);\n }\n\n },\n\n /**\n * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n * @instance\n */\n getRoot: function() {\n var gui = this;\n while (gui.parent) {\n gui = gui.parent;\n }\n return gui;\n },\n\n /**\n * @returns {Object} a JSON object representing the current state of\n * this GUI as well as its remembered properties.\n * @instance\n */\n getSaveObject: function() {\n\n var toReturn = this.load;\n\n toReturn.closed = this.closed;\n\n // Am I remembering any values?\n if (this.__rememberedObjects.length > 0) {\n\n toReturn.preset = this.preset;\n\n if (!toReturn.remembered) {\n toReturn.remembered = {};\n }\n\n toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n }\n\n toReturn.folders = {};\n common.each(this.__folders, function(element, key) {\n toReturn.folders[key] = element.getSaveObject();\n });\n\n return toReturn;\n\n },\n\n save: function() {\n\n if (!this.load.remembered) {\n this.load.remembered = {};\n }\n\n this.load.remembered[this.preset] = getCurrentPreset(this);\n markPresetModified(this, false);\n\n },\n\n saveAs: function(presetName) {\n\n if (!this.load.remembered) {\n\n // Retain default values upon first save\n this.load.remembered = {};\n this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n }\n\n this.load.remembered[presetName] = getCurrentPreset(this);\n this.preset = presetName;\n addPresetOption(this, presetName, true);\n\n },\n\n revert: function(gui) {\n\n common.each(this.__controllers, function(controller) {\n // Make revert work on Default.\n if (!this.getRoot().load.remembered) {\n controller.setValue(controller.initialValue);\n } else {\n recallSavedValue(gui || this.getRoot(), controller);\n }\n }, this);\n\n common.each(this.__folders, function(folder) {\n folder.revert(folder);\n });\n\n if (!gui) {\n markPresetModified(this.getRoot(), false);\n }\n\n\n },\n\n listen: function(controller) {\n\n var init = this.__listening.length == 0;\n this.__listening.push(controller);\n if (init) updateDisplays(this.__listening);\n\n }\n\n }\n\n );\n\n function add(gui, object, property, params) {\n\n if (object[property] === undefined) {\n throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n }\n\n var controller;\n\n if (params.color) {\n\n controller = new ColorController(object, property);\n\n } else {\n\n var factoryArgs = [object,property].concat(params.factoryArgs);\n controller = controllerFactory.apply(gui, factoryArgs);\n\n }\n\n if (params.before instanceof Controller) {\n params.before = params.before.__li;\n }\n\n recallSavedValue(gui, controller);\n\n dom.addClass(controller.domElement, 'c');\n\n var name = document.createElement('span');\n dom.addClass(name, 'property-name');\n name.innerHTML = controller.property;\n\n var container = document.createElement('div');\n container.appendChild(name);\n container.appendChild(controller.domElement);\n\n var li = addRow(gui, container, params.before);\n\n dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n dom.addClass(li, typeof controller.getValue());\n\n augmentController(gui, li, controller);\n\n gui.__controllers.push(controller);\n\n return controller;\n\n }\n\n /**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [dom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n */\n function addRow(gui, dom, liBefore) {\n var li = document.createElement('li');\n if (dom) li.appendChild(dom);\n if (liBefore) {\n gui.__ul.insertBefore(li, params.before);\n } else {\n gui.__ul.appendChild(li);\n }\n gui.onResize();\n return li;\n }\n\n function augmentController(gui, li, controller) {\n\n controller.__li = li;\n controller.__gui = gui;\n\n common.extend(controller, {\n\n options: function(options) {\n\n if (arguments.length > 1) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [common.toArray(arguments)]\n }\n );\n\n }\n\n if (common.isArray(options) || common.isObject(options)) {\n controller.remove();\n\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [options]\n }\n );\n\n }\n\n },\n\n name: function(v) {\n controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n return controller;\n },\n\n listen: function() {\n controller.__gui.listen(controller);\n return controller;\n },\n\n remove: function() {\n controller.__gui.remove(controller);\n return controller;\n }\n\n });\n\n // All sliders should be accompanied by a box.\n if (controller instanceof NumberControllerSlider) {\n\n var box = new NumberControllerBox(controller.object, controller.property,\n { min: controller.__min, max: controller.__max, step: controller.__step });\n\n common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n var pc = controller[method];\n var pb = box[method];\n controller[method] = box[method] = function() {\n var args = Array.prototype.slice.call(arguments);\n pc.apply(controller, args);\n return pb.apply(box, args);\n }\n });\n\n dom.addClass(li, 'has-slider');\n controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n }\n else if (controller instanceof NumberControllerBox) {\n\n var r = function(returned) {\n\n // Have we defined both boundaries?\n if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n // Well, then lets just replace this with a slider.\n controller.remove();\n return add(\n gui,\n controller.object,\n controller.property,\n {\n before: controller.__li.nextElementSibling,\n factoryArgs: [controller.__min, controller.__max, controller.__step]\n });\n\n }\n\n return returned;\n\n };\n\n controller.min = common.compose(r, controller.min);\n controller.max = common.compose(r, controller.max);\n\n }\n else if (controller instanceof BooleanController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__checkbox, 'click');\n });\n\n dom.bind(controller.__checkbox, 'click', function(e) {\n e.stopPropagation(); // Prevents double-toggle\n })\n\n }\n else if (controller instanceof FunctionController) {\n\n dom.bind(li, 'click', function() {\n dom.fakeEvent(controller.__button, 'click');\n });\n\n dom.bind(li, 'mouseover', function() {\n dom.addClass(controller.__button, 'hover');\n });\n\n dom.bind(li, 'mouseout', function() {\n dom.removeClass(controller.__button, 'hover');\n });\n\n }\n else if (controller instanceof ColorController) {\n\n dom.addClass(li, 'color');\n controller.updateDisplay = common.compose(function(r) {\n li.style.borderLeftColor = controller.__color.toString();\n return r;\n }, controller.updateDisplay);\n\n controller.updateDisplay();\n\n }\n\n controller.setValue = common.compose(function(r) {\n if (gui.getRoot().__preset_select && controller.isModified()) {\n markPresetModified(gui.getRoot(), true);\n }\n return r;\n }, controller.setValue);\n\n }\n\n function recallSavedValue(gui, controller) {\n\n // Find the topmost GUI, that's where remembered objects live.\n var root = gui.getRoot();\n\n // Does the object we're controlling match anything we've been told to\n // remember?\n var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n // Why yes, it does!\n if (matched_index != -1) {\n\n // Let me fetch a map of controllers for thcommon.isObject.\n var controller_map =\n root.__rememberedObjectIndecesToControllers[matched_index];\n\n // Ohp, I believe this is the first controller we've created for this\n // object. Lets make the map fresh.\n if (controller_map === undefined) {\n controller_map = {};\n root.__rememberedObjectIndecesToControllers[matched_index] =\n controller_map;\n }\n\n // Keep track of this controller\n controller_map[controller.property] = controller;\n\n // Okay, now have we saved any values for this controller?\n if (root.load && root.load.remembered) {\n\n var preset_map = root.load.remembered;\n\n // Which preset are we trying to load?\n var preset;\n\n if (preset_map[gui.preset]) {\n\n preset = preset_map[gui.preset];\n\n } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n // Uhh, you can have the default instead?\n preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n } else {\n\n // Nada.\n\n return;\n\n }\n\n\n // Did the loaded object remember thcommon.isObject?\n if (preset[matched_index] &&\n\n // Did we remember this particular property?\n preset[matched_index][controller.property] !== undefined) {\n\n // We did remember something for this guy ...\n var value = preset[matched_index][controller.property];\n\n // And that's what it is.\n controller.initialValue = value;\n controller.setValue(value);\n\n }\n\n }\n\n }\n\n }\n\n function getLocalStorageHash(gui, key) {\n // TODO how does this deal with multiple GUI's?\n return document.location.href + '.' + key;\n\n }\n\n function addSaveMenu(gui) {\n\n var div = gui.__save_row = document.createElement('li');\n\n dom.addClass(gui.domElement, 'has-save');\n\n gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n dom.addClass(div, 'save-row');\n\n var gears = document.createElement('span');\n gears.innerHTML = ' ';\n dom.addClass(gears, 'button gears');\n\n // TODO replace with FunctionController\n var button = document.createElement('span');\n button.innerHTML = 'Save';\n dom.addClass(button, 'button');\n dom.addClass(button, 'save');\n\n var button2 = document.createElement('span');\n button2.innerHTML = 'New';\n dom.addClass(button2, 'button');\n dom.addClass(button2, 'save-as');\n\n var button3 = document.createElement('span');\n button3.innerHTML = 'Revert';\n dom.addClass(button3, 'button');\n dom.addClass(button3, 'revert');\n\n var select = gui.__preset_select = document.createElement('select');\n\n if (gui.load && gui.load.remembered) {\n\n common.each(gui.load.remembered, function(value, key) {\n addPresetOption(gui, key, key == gui.preset);\n });\n\n } else {\n addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n }\n\n dom.bind(select, 'change', function() {\n\n\n for (var index = 0; index < gui.__preset_select.length; index++) {\n gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n }\n\n gui.preset = this.value;\n\n });\n\n div.appendChild(select);\n div.appendChild(gears);\n div.appendChild(button);\n div.appendChild(button2);\n div.appendChild(button3);\n\n if (SUPPORTS_LOCAL_STORAGE) {\n\n var saveLocally = document.getElementById('dg-save-locally');\n var explain = document.getElementById('dg-local-explain');\n\n saveLocally.style.display = 'block';\n\n var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n localStorageCheckBox.setAttribute('checked', 'checked');\n }\n\n function showHideExplain() {\n explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n }\n\n showHideExplain();\n\n // TODO: Use a boolean controller, fool!\n dom.bind(localStorageCheckBox, 'change', function() {\n gui.useLocalStorage = !gui.useLocalStorage;\n showHideExplain();\n });\n\n }\n\n var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n dom.bind(newConstructorTextArea, 'keydown', function(e) {\n if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n SAVE_DIALOGUE.hide();\n }\n });\n\n dom.bind(gears, 'click', function() {\n newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n SAVE_DIALOGUE.show();\n newConstructorTextArea.focus();\n newConstructorTextArea.select();\n });\n\n dom.bind(button, 'click', function() {\n gui.save();\n });\n\n dom.bind(button2, 'click', function() {\n var presetName = prompt('Enter a new preset name.');\n if (presetName) gui.saveAs(presetName);\n });\n\n dom.bind(button3, 'click', function() {\n gui.revert();\n });\n\n// div.appendChild(button2);\n\n }\n\n function addResizeHandle(gui) {\n\n gui.__resize_handle = document.createElement('div');\n\n common.extend(gui.__resize_handle.style, {\n\n width: '6px',\n marginLeft: '-3px',\n height: '200px',\n cursor: 'ew-resize',\n position: 'absolute'\n// border: '1px solid blue'\n\n });\n\n var pmouseX;\n\n dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n function dragStart(e) {\n\n e.preventDefault();\n\n pmouseX = e.clientX;\n\n dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.bind(window, 'mousemove', drag);\n dom.bind(window, 'mouseup', dragStop);\n\n return false;\n\n }\n\n function drag(e) {\n\n e.preventDefault();\n\n gui.width += pmouseX - e.clientX;\n gui.onResize();\n pmouseX = e.clientX;\n\n return false;\n\n }\n\n function dragStop() {\n\n dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n dom.unbind(window, 'mousemove', drag);\n dom.unbind(window, 'mouseup', dragStop);\n\n }\n\n }\n\n function setWidth(gui, w) {\n gui.domElement.style.width = w + 'px';\n // Auto placed save-rows are position fixed, so we have to\n // set the width manually if we want it to bleed to the edge\n if (gui.__save_row && gui.autoPlace) {\n gui.__save_row.style.width = w + 'px';\n }if (gui.__closeButton) {\n gui.__closeButton.style.width = w + 'px';\n }\n }\n\n function getCurrentPreset(gui, useInitialValues) {\n\n var toReturn = {};\n\n // For each object I'm remembering\n common.each(gui.__rememberedObjects, function(val, index) {\n\n var saved_values = {};\n\n // The controllers I've made for thcommon.isObject by property\n var controller_map =\n gui.__rememberedObjectIndecesToControllers[index];\n\n // Remember each value for each property\n common.each(controller_map, function(controller, property) {\n saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n });\n\n // Save the values for thcommon.isObject\n toReturn[index] = saved_values;\n\n });\n\n return toReturn;\n\n }\n\n function addPresetOption(gui, name, setSelected) {\n var opt = document.createElement('option');\n opt.innerHTML = name;\n opt.value = name;\n gui.__preset_select.appendChild(opt);\n if (setSelected) {\n gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n }\n }\n\n function setPresetSelectIndex(gui) {\n for (var index = 0; index < gui.__preset_select.length; index++) {\n if (gui.__preset_select[index].value == gui.preset) {\n gui.__preset_select.selectedIndex = index;\n }\n }\n }\n\n function markPresetModified(gui, modified) {\n var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n// console.log('mark', modified, opt);\n if (modified) {\n opt.innerHTML = opt.value + \"*\";\n } else {\n opt.innerHTML = opt.value;\n }\n }\n\n function updateDisplays(controllerArray) {\n\n\n if (controllerArray.length != 0) {\n\n requestAnimationFrame(function() {\n updateDisplays(controllerArray);\n });\n\n }\n\n common.each(controllerArray, function(c) {\n c.updateDisplay();\n });\n\n }\n\n return GUI;\n\n})(dat.utils.css,\n\"
      \\n\\n Here's the new load parameter for your GUI's constructor:\\n\\n \\n\\n
      \\n\\n Automatically save\\n values to localStorage on exit.\\n\\n
      The values saved to localStorage will\\n override those passed to dat.GUI's constructor. This makes it\\n easier to work incrementally, but localStorage is fragile,\\n and your friends may not see the same values you do.\\n \\n
      \\n \\n
      \\n\\n
      \",\n\".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\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n return function(object, property) {\n\n var initialValue = object[property];\n\n // Providing options?\n if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n return new OptionController(object, property, arguments[2]);\n }\n\n // Providing a map?\n\n if (common.isNumber(initialValue)) {\n\n if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n // Has min and max.\n return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n } else {\n\n return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n }\n\n }\n\n if (common.isString(initialValue)) {\n return new StringController(object, property);\n }\n\n if (common.isFunction(initialValue)) {\n return new FunctionController(object, property, '');\n }\n\n if (common.isBoolean(initialValue)) {\n return new BooleanController(object, property);\n }\n\n }\n\n })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n /**\n * @class Provides a text input to alter the string property of an object.\n *\n * @extends dat.controllers.Controller\n *\n * @param {Object} object The object to be manipulated\n * @param {string} property The name of the property to be manipulated\n *\n * @member dat.controllers\n */\n var StringController = function(object, property) {\n\n StringController.superclass.call(this, object, property);\n\n var _this = this;\n\n this.__input = document.createElement('input');\n this.__input.setAttribute('type', 'text');\n\n dom.bind(this.__input, 'keyup', onChange);\n dom.bind(this.__input, 'change', onChange);\n dom.bind(this.__input, 'blur', onBlur);\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) {\n this.blur();\n }\n });\n \n\n function onChange() {\n _this.setValue(_this.__input.value);\n }\n\n function onBlur() {\n if (_this.__onFinishChange) {\n _this.__onFinishChange.call(_this, _this.getValue());\n }\n }\n\n this.updateDisplay();\n\n this.domElement.appendChild(this.__input);\n\n };\n\n StringController.superclass = Controller;\n\n common.extend(\n\n StringController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n // Stops the caret from moving on account of:\n // keyup -> setValue -> updateDisplay\n if (!dom.isActive(this.__input)) {\n this.__input.value = this.getValue();\n }\n return StringController.superclass.prototype.updateDisplay.call(this);\n }\n\n }\n\n );\n\n return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n var ColorController = function(object, property) {\n\n ColorController.superclass.call(this, object, property);\n\n this.__color = new Color(this.getValue());\n this.__temp = new Color(0);\n\n var _this = this;\n\n this.domElement = document.createElement('div');\n\n dom.makeSelectable(this.domElement, false);\n\n this.__selector = document.createElement('div');\n this.__selector.className = 'selector';\n\n this.__saturation_field = document.createElement('div');\n this.__saturation_field.className = 'saturation-field';\n\n this.__field_knob = document.createElement('div');\n this.__field_knob.className = 'field-knob';\n this.__field_knob_border = '2px solid ';\n\n this.__hue_knob = document.createElement('div');\n this.__hue_knob.className = 'hue-knob';\n\n this.__hue_field = document.createElement('div');\n this.__hue_field.className = 'hue-field';\n\n this.__input = document.createElement('input');\n this.__input.type = 'text';\n this.__input_textShadow = '0 1px 1px ';\n\n dom.bind(this.__input, 'keydown', function(e) {\n if (e.keyCode === 13) { // on enter\n onBlur.call(this);\n }\n });\n\n dom.bind(this.__input, 'blur', onBlur);\n\n dom.bind(this.__selector, 'mousedown', function(e) {\n\n dom\n .addClass(this, 'drag')\n .bind(window, 'mouseup', function(e) {\n dom.removeClass(_this.__selector, 'drag');\n });\n\n });\n\n var value_field = document.createElement('div');\n\n common.extend(this.__selector.style, {\n width: '122px',\n height: '102px',\n padding: '3px',\n backgroundColor: '#222',\n boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n });\n\n common.extend(this.__field_knob.style, {\n position: 'absolute',\n width: '12px',\n height: '12px',\n border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n borderRadius: '12px',\n zIndex: 1\n });\n \n common.extend(this.__hue_knob.style, {\n position: 'absolute',\n width: '15px',\n height: '2px',\n borderRight: '4px solid #fff',\n zIndex: 1\n });\n\n common.extend(this.__saturation_field.style, {\n width: '100px',\n height: '100px',\n border: '1px solid #555',\n marginRight: '3px',\n display: 'inline-block',\n cursor: 'pointer'\n });\n\n common.extend(value_field.style, {\n width: '100%',\n height: '100%',\n background: 'none'\n });\n \n linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n common.extend(this.__hue_field.style, {\n width: '15px',\n height: '100px',\n display: 'inline-block',\n border: '1px solid #555',\n cursor: 'ns-resize'\n });\n\n hueGradient(this.__hue_field);\n\n common.extend(this.__input.style, {\n outline: 'none',\n// width: '120px',\n textAlign: 'center',\n// padding: '4px',\n// marginBottom: '6px',\n color: '#fff',\n border: 0,\n fontWeight: 'bold',\n textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n });\n\n dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n dom.bind(this.__hue_field, 'mousedown', function(e) {\n setH(e);\n dom.bind(window, 'mousemove', setH);\n dom.bind(window, 'mouseup', unbindH);\n });\n\n function fieldDown(e) {\n setSV(e);\n // document.body.style.cursor = 'none';\n dom.bind(window, 'mousemove', setSV);\n dom.bind(window, 'mouseup', unbindSV);\n }\n\n function unbindSV() {\n dom.unbind(window, 'mousemove', setSV);\n dom.unbind(window, 'mouseup', unbindSV);\n // document.body.style.cursor = 'default';\n }\n\n function onBlur() {\n var i = interpret(this.value);\n if (i !== false) {\n _this.__color.__state = i;\n _this.setValue(_this.__color.toOriginal());\n } else {\n this.value = _this.__color.toString();\n }\n }\n\n function unbindH() {\n dom.unbind(window, 'mousemove', setH);\n dom.unbind(window, 'mouseup', unbindH);\n }\n\n this.__saturation_field.appendChild(value_field);\n this.__selector.appendChild(this.__field_knob);\n this.__selector.appendChild(this.__saturation_field);\n this.__selector.appendChild(this.__hue_field);\n this.__hue_field.appendChild(this.__hue_knob);\n\n this.domElement.appendChild(this.__input);\n this.domElement.appendChild(this.__selector);\n\n this.updateDisplay();\n\n function setSV(e) {\n\n e.preventDefault();\n\n var w = dom.getWidth(_this.__saturation_field);\n var o = dom.getOffset(_this.__saturation_field);\n var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n if (v > 1) v = 1;\n else if (v < 0) v = 0;\n\n if (s > 1) s = 1;\n else if (s < 0) s = 0;\n\n _this.__color.v = v;\n _this.__color.s = s;\n\n _this.setValue(_this.__color.toOriginal());\n\n\n return false;\n\n }\n\n function setH(e) {\n\n e.preventDefault();\n\n var s = dom.getHeight(_this.__hue_field);\n var o = dom.getOffset(_this.__hue_field);\n var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n if (h > 1) h = 1;\n else if (h < 0) h = 0;\n\n _this.__color.h = h * 360;\n\n _this.setValue(_this.__color.toOriginal());\n\n return false;\n\n }\n\n };\n\n ColorController.superclass = Controller;\n\n common.extend(\n\n ColorController.prototype,\n Controller.prototype,\n\n {\n\n updateDisplay: function() {\n\n var i = interpret(this.getValue());\n\n if (i !== false) {\n\n var mismatch = false;\n\n // Check for mismatch on the interpreted value.\n\n common.each(Color.COMPONENTS, function(component) {\n if (!common.isUndefined(i[component]) &&\n !common.isUndefined(this.__color.__state[component]) &&\n i[component] !== this.__color.__state[component]) {\n mismatch = true;\n return {}; // break\n }\n }, this);\n\n // If nothing diverges, we keep our previous values\n // for statefulness, otherwise we recalculate fresh\n if (mismatch) {\n common.extend(this.__color.__state, i);\n }\n\n }\n\n common.extend(this.__temp.__state, this.__color.__state);\n\n this.__temp.a = 1;\n\n var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n var _flip = 255 - flip;\n\n common.extend(this.__field_knob.style, {\n marginLeft: 100 * this.__color.s - 7 + 'px',\n marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n backgroundColor: this.__temp.toString(),\n border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n });\n\n this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n this.__temp.s = 1;\n this.__temp.v = 1;\n\n linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n common.extend(this.__input.style, {\n backgroundColor: this.__input.value = this.__color.toString(),\n color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n });\n\n }\n\n }\n\n );\n \n var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n \n function linearGradient(elem, x, a, b) {\n elem.style.background = '';\n common.each(vendors, function(vendor) {\n elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n });\n }\n \n function hueGradient(elem) {\n elem.style.background = '';\n elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n }\n\n\n return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n /**\n * requirejs version of Paul Irish's RequestAnimationFrame\n * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n */\n\n return window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function(callback, element) {\n\n window.setTimeout(callback, 1000 / 60);\n\n };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n var CenteredDiv = function() {\n\n this.backgroundElement = document.createElement('div');\n common.extend(this.backgroundElement.style, {\n backgroundColor: 'rgba(0,0,0,0.8)',\n top: 0,\n left: 0,\n display: 'none',\n zIndex: '1000',\n opacity: 0,\n WebkitTransition: 'opacity 0.2s linear'\n });\n\n dom.makeFullscreen(this.backgroundElement);\n this.backgroundElement.style.position = 'fixed';\n\n this.domElement = document.createElement('div');\n common.extend(this.domElement.style, {\n position: 'fixed',\n display: 'none',\n zIndex: '1001',\n opacity: 0,\n WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n });\n\n\n document.body.appendChild(this.backgroundElement);\n document.body.appendChild(this.domElement);\n\n var _this = this;\n dom.bind(this.backgroundElement, 'click', function() {\n _this.hide();\n });\n\n\n };\n\n CenteredDiv.prototype.show = function() {\n\n var _this = this;\n \n\n\n this.backgroundElement.style.display = 'block';\n\n this.domElement.style.display = 'block';\n this.domElement.style.opacity = 0;\n// this.domElement.style.top = '52%';\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n this.layout();\n\n common.defer(function() {\n _this.backgroundElement.style.opacity = 1;\n _this.domElement.style.opacity = 1;\n _this.domElement.style.webkitTransform = 'scale(1)';\n });\n\n };\n\n CenteredDiv.prototype.hide = function() {\n\n var _this = this;\n\n var hide = function() {\n\n _this.domElement.style.display = 'none';\n _this.backgroundElement.style.display = 'none';\n\n dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n dom.unbind(_this.domElement, 'transitionend', hide);\n dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n };\n\n dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n dom.bind(this.domElement, 'transitionend', hide);\n dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n this.backgroundElement.style.opacity = 0;\n// this.domElement.style.top = '48%';\n this.domElement.style.opacity = 0;\n this.domElement.style.webkitTransform = 'scale(1.1)';\n\n };\n\n CenteredDiv.prototype.layout = function() {\n this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n };\n \n function lockScroll(e) {\n console.log(e);\n }\n\n return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.gui.js\n// module id = 2\n// module chunks = 0","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n \n var ARR_EACH = Array.prototype.forEach;\n var ARR_SLICE = Array.prototype.slice;\n\n /**\n * Band-aid methods for things that should be a lot easier in JavaScript.\n * Implementation and structure inspired by underscore.js\n * http://documentcloud.github.com/underscore/\n */\n\n return { \n \n BREAK: {},\n \n extend: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (!this.isUndefined(obj[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n defaults: function(target) {\n \n this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n \n for (var key in obj)\n if (this.isUndefined(target[key])) \n target[key] = obj[key];\n \n }, this);\n \n return target;\n \n },\n \n compose: function() {\n var toCall = ARR_SLICE.call(arguments);\n return function() {\n var args = ARR_SLICE.call(arguments);\n for (var i = toCall.length -1; i >= 0; i--) {\n args = [toCall[i].apply(this, args)];\n }\n return args[0];\n }\n },\n \n each: function(obj, itr, scope) {\n\n \n if (ARR_EACH && obj.forEach === ARR_EACH) { \n \n obj.forEach(itr, scope);\n \n } else if (obj.length === obj.length + 0) { // Is number but not NaN\n \n for (var key = 0, l = obj.length; key < l; key++)\n if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n return;\n \n } else {\n\n for (var key in obj) \n if (itr.call(scope, obj[key], key) === this.BREAK)\n return;\n \n }\n \n },\n \n defer: function(fnc) {\n setTimeout(fnc, 0);\n },\n \n toArray: function(obj) {\n if (obj.toArray) return obj.toArray();\n return ARR_SLICE.call(obj);\n },\n\n isUndefined: function(obj) {\n return obj === undefined;\n },\n \n isNull: function(obj) {\n return obj === null;\n },\n \n isNaN: function(obj) {\n return obj !== obj;\n },\n \n isArray: Array.isArray || function(obj) {\n return obj.constructor === Array;\n },\n \n isObject: function(obj) {\n return obj === Object(obj);\n },\n \n isNumber: function(obj) {\n return obj === obj+0;\n },\n \n isString: function(obj) {\n return obj === obj+'';\n },\n \n isBoolean: function(obj) {\n return obj === false || obj === true;\n },\n \n isFunction: function(obj) {\n return Object.prototype.toString.call(obj) === '[object Function]';\n }\n \n };\n \n})();\n\n\ndat.color.toString = (function (common) {\n\n return function(color) {\n\n if (color.a == 1 || common.isUndefined(color.a)) {\n\n var s = color.hex.toString(16);\n while (s.length < 6) {\n s = '0' + s;\n }\n\n return '#' + s;\n\n } else {\n\n return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n }\n\n }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n var Color = function() {\n\n this.__state = interpret.apply(this, arguments);\n\n if (this.__state === false) {\n throw 'Failed to interpret color arguments';\n }\n\n this.__state.a = this.__state.a || 1;\n\n\n };\n\n Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n common.extend(Color.prototype, {\n\n toString: function() {\n return toString(this);\n },\n\n toOriginal: function() {\n return this.__state.conversion.write(this);\n }\n\n });\n\n defineRGBComponent(Color.prototype, 'r', 2);\n defineRGBComponent(Color.prototype, 'g', 1);\n defineRGBComponent(Color.prototype, 'b', 0);\n\n defineHSVComponent(Color.prototype, 'h');\n defineHSVComponent(Color.prototype, 's');\n defineHSVComponent(Color.prototype, 'v');\n\n Object.defineProperty(Color.prototype, 'a', {\n\n get: function() {\n return this.__state.a;\n },\n\n set: function(v) {\n this.__state.a = v;\n }\n\n });\n\n Object.defineProperty(Color.prototype, 'hex', {\n\n get: function() {\n\n if (!this.__state.space !== 'HEX') {\n this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n }\n\n return this.__state.hex;\n\n },\n\n set: function(v) {\n\n this.__state.space = 'HEX';\n this.__state.hex = v;\n\n }\n\n });\n\n function defineRGBComponent(target, component, componentHexIndex) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'RGB') {\n return this.__state[component];\n }\n\n recalculateRGB(this, component, componentHexIndex);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'RGB') {\n recalculateRGB(this, component, componentHexIndex);\n this.__state.space = 'RGB';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function defineHSVComponent(target, component) {\n\n Object.defineProperty(target, component, {\n\n get: function() {\n\n if (this.__state.space === 'HSV')\n return this.__state[component];\n\n recalculateHSV(this);\n\n return this.__state[component];\n\n },\n\n set: function(v) {\n\n if (this.__state.space !== 'HSV') {\n recalculateHSV(this);\n this.__state.space = 'HSV';\n }\n\n this.__state[component] = v;\n\n }\n\n });\n\n }\n\n function recalculateRGB(color, component, componentHexIndex) {\n\n if (color.__state.space === 'HEX') {\n\n color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n } else if (color.__state.space === 'HSV') {\n\n common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n } else {\n\n throw 'Corrupted color state';\n\n }\n\n }\n\n function recalculateHSV(color) {\n\n var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n common.extend(color.__state,\n {\n s: result.s,\n v: result.v\n }\n );\n\n if (!common.isNaN(result.h)) {\n color.__state.h = result.h;\n } else if (common.isUndefined(color.__state.h)) {\n color.__state.h = 0;\n }\n\n }\n\n return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n var result, toReturn;\n\n var interpret = function() {\n\n toReturn = false;\n\n var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n common.each(INTERPRETATIONS, function(family) {\n\n if (family.litmus(original)) {\n\n common.each(family.conversions, function(conversion, conversionName) {\n\n result = conversion.read(original);\n\n if (toReturn === false && result !== false) {\n toReturn = result;\n result.conversionName = conversionName;\n result.conversion = conversion;\n return common.BREAK;\n\n }\n\n });\n\n return common.BREAK;\n\n }\n\n });\n\n return toReturn;\n\n };\n\n var INTERPRETATIONS = [\n\n // Strings\n {\n\n litmus: common.isString,\n\n conversions: {\n\n THREE_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt(\n '0x' +\n test[1].toString() + test[1].toString() +\n test[2].toString() + test[2].toString() +\n test[3].toString() + test[3].toString())\n };\n\n },\n\n write: toString\n\n },\n\n SIX_CHAR_HEX: {\n\n read: function(original) {\n\n var test = original.match(/^#([A-F0-9]{6})$/i);\n if (test === null) return false;\n\n return {\n space: 'HEX',\n hex: parseInt('0x' + test[1].toString())\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGB: {\n\n read: function(original) {\n\n var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3])\n };\n\n },\n\n write: toString\n\n },\n\n CSS_RGBA: {\n\n read: function(original) {\n\n var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n if (test === null) return false;\n\n return {\n space: 'RGB',\n r: parseFloat(test[1]),\n g: parseFloat(test[2]),\n b: parseFloat(test[3]),\n a: parseFloat(test[4])\n };\n\n },\n\n write: toString\n\n }\n\n }\n\n },\n\n // Numbers\n {\n\n litmus: common.isNumber,\n\n conversions: {\n\n HEX: {\n read: function(original) {\n return {\n space: 'HEX',\n hex: original,\n conversionName: 'HEX'\n }\n },\n\n write: function(color) {\n return color.hex;\n }\n }\n\n }\n\n },\n\n // Arrays\n {\n\n litmus: common.isArray,\n\n conversions: {\n\n RGB_ARRAY: {\n read: function(original) {\n if (original.length != 3) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b];\n }\n\n },\n\n RGBA_ARRAY: {\n read: function(original) {\n if (original.length != 4) return false;\n return {\n space: 'RGB',\n r: original[0],\n g: original[1],\n b: original[2],\n a: original[3]\n };\n },\n\n write: function(color) {\n return [color.r, color.g, color.b, color.a];\n }\n\n }\n\n }\n\n },\n\n // Objects\n {\n\n litmus: common.isObject,\n\n conversions: {\n\n RGBA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b) &&\n common.isNumber(original.a)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b,\n a: color.a\n }\n }\n },\n\n RGB_OBJ: {\n read: function(original) {\n if (common.isNumber(original.r) &&\n common.isNumber(original.g) &&\n common.isNumber(original.b)) {\n return {\n space: 'RGB',\n r: original.r,\n g: original.g,\n b: original.b\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n r: color.r,\n g: color.g,\n b: color.b\n }\n }\n },\n\n HSVA_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v) &&\n common.isNumber(original.a)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v,\n a: original.a\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v,\n a: color.a\n }\n }\n },\n\n HSV_OBJ: {\n read: function(original) {\n if (common.isNumber(original.h) &&\n common.isNumber(original.s) &&\n common.isNumber(original.v)) {\n return {\n space: 'HSV',\n h: original.h,\n s: original.s,\n v: original.v\n }\n }\n return false;\n },\n\n write: function(color) {\n return {\n h: color.h,\n s: color.s,\n v: color.v\n }\n }\n\n }\n\n }\n\n }\n\n\n ];\n\n return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n var tmpComponent;\n\n return {\n\n hsv_to_rgb: function(h, s, v) {\n\n var hi = Math.floor(h / 60) % 6;\n\n var f = h / 60 - Math.floor(h / 60);\n var p = v * (1.0 - s);\n var q = v * (1.0 - (f * s));\n var t = v * (1.0 - ((1.0 - f) * s));\n var c = [\n [v, t, p],\n [q, v, p],\n [p, v, t],\n [p, q, v],\n [t, p, v],\n [v, p, q]\n ][hi];\n\n return {\n r: c[0] * 255,\n g: c[1] * 255,\n b: c[2] * 255\n };\n\n },\n\n rgb_to_hsv: function(r, g, b) {\n\n var min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n delta = max - min,\n h, s;\n\n if (max != 0) {\n s = delta / max;\n } else {\n return {\n h: NaN,\n s: 0,\n v: 0\n };\n }\n\n if (r == max) {\n h = (g - b) / delta;\n } else if (g == max) {\n h = 2 + (b - r) / delta;\n } else {\n h = 4 + (r - g) / delta;\n }\n h /= 6;\n if (h < 0) {\n h += 1;\n }\n\n return {\n h: h * 360,\n s: s,\n v: max / 255\n };\n },\n\n rgb_to_hex: function(r, g, b) {\n var hex = this.hex_with_component(0, 2, r);\n hex = this.hex_with_component(hex, 1, g);\n hex = this.hex_with_component(hex, 0, b);\n return hex;\n },\n\n component_from_hex: function(hex, componentIndex) {\n return (hex >> (componentIndex * 8)) & 0xFF;\n },\n\n hex_with_component: function(hex, componentIndex, value) {\n return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n }\n\n }\n\n})(),\ndat.color.toString,\ndat.utils.common);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/dat-gui/vendor/dat.color.js\n// module id = 3\n// module chunks = 0","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/stats-js/build/stats.min.js\n// module id = 4\n// module chunks = 0","const THREE = require('three');\r\n\r\nexport var ProxyMaterial = new THREE.MeshLambertMaterial({\r\n color: 0xff0000\r\n});\r\n\r\nexport const PROXY_BUFFER_SIZE = 4;\r\n\r\nexport default class ProxyGeometry {\r\n constructor(bounds) {\r\n this.group = new THREE.Group();\r\n this._buffer = new Float32Array();\r\n }\r\n\r\n add(mesh) {\r\n this.group.add(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n remove(mesh) {\r\n this.group.remove(mesh);\r\n this._buffer = new Float32Array(PROXY_BUFFER_SIZE * this.group.children.length);\r\n this.computeBuffer();\r\n }\r\n\r\n update(t = 1/60) {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n // TODO: animate objects\r\n }\r\n this.computeBuffer();\r\n }\r\n\r\n computeBuffer() {\r\n const {children} = this.group;\r\n for (let i = 0; i < children.length; ++i) {\r\n const child = children[i];\r\n this._buffer[PROXY_BUFFER_SIZE*i] = child.position.x;\r\n this._buffer[PROXY_BUFFER_SIZE*i+1] = child.position.y;\r\n this._buffer[PROXY_BUFFER_SIZE*i+2] = child.position.z;\r\n\r\n if (child.geometry instanceof THREE.BoxGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 0;\r\n } else if (child.geometry instanceof THREE.SphereGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 1;\r\n } else if (child.geometry instanceof THREE.ConeGeometry) {\r\n this._buffer[PROXY_BUFFER_SIZE*i+3] = 2;\r\n }\r\n }\r\n }\r\n\r\n get buffer() {\r\n return this._buffer;\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/proxy_geometry.js","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.THREE = global.THREE || {})));\n}(this, (function (exports) { 'use strict';\n\n\t// Polyfills\n\n\tif ( Number.EPSILON === undefined ) {\n\n\t\tNumber.EPSILON = Math.pow( 2, - 52 );\n\n\t}\n\n\t//\n\n\tif ( Math.sign === undefined ) {\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign\n\n\t\tMath.sign = function ( x ) {\n\n\t\t\treturn ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;\n\n\t\t};\n\n\t}\n\n\tif ( Function.prototype.name === undefined ) {\n\n\t\t// Missing in IE9-11.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name\n\n\t\tObject.defineProperty( Function.prototype, 'name', {\n\n\t\t\tget: function () {\n\n\t\t\t\treturn this.toString().match( /^\\s*function\\s*([^\\(\\s]*)/ )[ 1 ];\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tif ( Object.assign === undefined ) {\n\n\t\t// Missing in IE.\n\t\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\n\t\t( function () {\n\n\t\t\tObject.assign = function ( target ) {\n\n\t\t\t\t'use strict';\n\n\t\t\t\tif ( target === undefined || target === null ) {\n\n\t\t\t\t\tthrow new TypeError( 'Cannot convert undefined or null to object' );\n\n\t\t\t\t}\n\n\t\t\t\tvar output = Object( target );\n\n\t\t\t\tfor ( var index = 1; index < arguments.length; index ++ ) {\n\n\t\t\t\t\tvar source = arguments[ index ];\n\n\t\t\t\t\tif ( source !== undefined && source !== null ) {\n\n\t\t\t\t\t\tfor ( var nextKey in source ) {\n\n\t\t\t\t\t\t\tif ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {\n\n\t\t\t\t\t\t\t\toutput[ nextKey ] = source[ nextKey ];\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn output;\n\n\t\t\t};\n\n\t\t} )();\n\n\t}\n\n\t/**\n\t * https://github.com/mrdoob/eventdispatcher.js/\n\t */\n\n\tfunction EventDispatcher() {}\n\n\tEventDispatcher.prototype = {\n\n\t\taddEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) this._listeners = {};\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\tif ( listeners[ type ] === undefined ) {\n\n\t\t\t\tlisteners[ type ] = [];\n\n\t\t\t}\n\n\t\t\tif ( listeners[ type ].indexOf( listener ) === - 1 ) {\n\n\t\t\t\tlisteners[ type ].push( listener );\n\n\t\t\t}\n\n\t\t},\n\n\t\thasEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return false;\n\n\t\t\tvar listeners = this._listeners;\n\n\t\t\treturn listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;\n\n\t\t},\n\n\t\tremoveEventListener: function ( type, listener ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tvar index = listenerArray.indexOf( listener );\n\n\t\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\t\tlistenerArray.splice( index, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tdispatchEvent: function ( event ) {\n\n\t\t\tif ( this._listeners === undefined ) return;\n\n\t\t\tvar listeners = this._listeners;\n\t\t\tvar listenerArray = listeners[ event.type ];\n\n\t\t\tif ( listenerArray !== undefined ) {\n\n\t\t\t\tevent.target = this;\n\n\t\t\t\tvar array = [], i = 0;\n\t\t\t\tvar length = listenerArray.length;\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ] = listenerArray[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0; i < length; i ++ ) {\n\n\t\t\t\t\tarray[ i ].call( this, event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tvar REVISION = '84';\n\tvar MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\tvar CullFaceNone = 0;\n\tvar CullFaceBack = 1;\n\tvar CullFaceFront = 2;\n\tvar CullFaceFrontBack = 3;\n\tvar FrontFaceDirectionCW = 0;\n\tvar FrontFaceDirectionCCW = 1;\n\tvar BasicShadowMap = 0;\n\tvar PCFShadowMap = 1;\n\tvar PCFSoftShadowMap = 2;\n\tvar FrontSide = 0;\n\tvar BackSide = 1;\n\tvar DoubleSide = 2;\n\tvar FlatShading = 1;\n\tvar SmoothShading = 2;\n\tvar NoColors = 0;\n\tvar FaceColors = 1;\n\tvar VertexColors = 2;\n\tvar NoBlending = 0;\n\tvar NormalBlending = 1;\n\tvar AdditiveBlending = 2;\n\tvar SubtractiveBlending = 3;\n\tvar MultiplyBlending = 4;\n\tvar CustomBlending = 5;\n\tvar AddEquation = 100;\n\tvar SubtractEquation = 101;\n\tvar ReverseSubtractEquation = 102;\n\tvar MinEquation = 103;\n\tvar MaxEquation = 104;\n\tvar ZeroFactor = 200;\n\tvar OneFactor = 201;\n\tvar SrcColorFactor = 202;\n\tvar OneMinusSrcColorFactor = 203;\n\tvar SrcAlphaFactor = 204;\n\tvar OneMinusSrcAlphaFactor = 205;\n\tvar DstAlphaFactor = 206;\n\tvar OneMinusDstAlphaFactor = 207;\n\tvar DstColorFactor = 208;\n\tvar OneMinusDstColorFactor = 209;\n\tvar SrcAlphaSaturateFactor = 210;\n\tvar NeverDepth = 0;\n\tvar AlwaysDepth = 1;\n\tvar LessDepth = 2;\n\tvar LessEqualDepth = 3;\n\tvar EqualDepth = 4;\n\tvar GreaterEqualDepth = 5;\n\tvar GreaterDepth = 6;\n\tvar NotEqualDepth = 7;\n\tvar MultiplyOperation = 0;\n\tvar MixOperation = 1;\n\tvar AddOperation = 2;\n\tvar NoToneMapping = 0;\n\tvar LinearToneMapping = 1;\n\tvar ReinhardToneMapping = 2;\n\tvar Uncharted2ToneMapping = 3;\n\tvar CineonToneMapping = 4;\n\tvar UVMapping = 300;\n\tvar CubeReflectionMapping = 301;\n\tvar CubeRefractionMapping = 302;\n\tvar EquirectangularReflectionMapping = 303;\n\tvar EquirectangularRefractionMapping = 304;\n\tvar SphericalReflectionMapping = 305;\n\tvar CubeUVReflectionMapping = 306;\n\tvar CubeUVRefractionMapping = 307;\n\tvar RepeatWrapping = 1000;\n\tvar ClampToEdgeWrapping = 1001;\n\tvar MirroredRepeatWrapping = 1002;\n\tvar NearestFilter = 1003;\n\tvar NearestMipMapNearestFilter = 1004;\n\tvar NearestMipMapLinearFilter = 1005;\n\tvar LinearFilter = 1006;\n\tvar LinearMipMapNearestFilter = 1007;\n\tvar LinearMipMapLinearFilter = 1008;\n\tvar UnsignedByteType = 1009;\n\tvar ByteType = 1010;\n\tvar ShortType = 1011;\n\tvar UnsignedShortType = 1012;\n\tvar IntType = 1013;\n\tvar UnsignedIntType = 1014;\n\tvar FloatType = 1015;\n\tvar HalfFloatType = 1016;\n\tvar UnsignedShort4444Type = 1017;\n\tvar UnsignedShort5551Type = 1018;\n\tvar UnsignedShort565Type = 1019;\n\tvar UnsignedInt248Type = 1020;\n\tvar AlphaFormat = 1021;\n\tvar RGBFormat = 1022;\n\tvar RGBAFormat = 1023;\n\tvar LuminanceFormat = 1024;\n\tvar LuminanceAlphaFormat = 1025;\n\tvar RGBEFormat = RGBAFormat;\n\tvar DepthFormat = 1026;\n\tvar DepthStencilFormat = 1027;\n\tvar RGB_S3TC_DXT1_Format = 2001;\n\tvar RGBA_S3TC_DXT1_Format = 2002;\n\tvar RGBA_S3TC_DXT3_Format = 2003;\n\tvar RGBA_S3TC_DXT5_Format = 2004;\n\tvar RGB_PVRTC_4BPPV1_Format = 2100;\n\tvar RGB_PVRTC_2BPPV1_Format = 2101;\n\tvar RGBA_PVRTC_4BPPV1_Format = 2102;\n\tvar RGBA_PVRTC_2BPPV1_Format = 2103;\n\tvar RGB_ETC1_Format = 2151;\n\tvar LoopOnce = 2200;\n\tvar LoopRepeat = 2201;\n\tvar LoopPingPong = 2202;\n\tvar InterpolateDiscrete = 2300;\n\tvar InterpolateLinear = 2301;\n\tvar InterpolateSmooth = 2302;\n\tvar ZeroCurvatureEnding = 2400;\n\tvar ZeroSlopeEnding = 2401;\n\tvar WrapAroundEnding = 2402;\n\tvar TrianglesDrawMode = 0;\n\tvar TriangleStripDrawMode = 1;\n\tvar TriangleFanDrawMode = 2;\n\tvar LinearEncoding = 3000;\n\tvar sRGBEncoding = 3001;\n\tvar GammaEncoding = 3007;\n\tvar RGBEEncoding = 3002;\n\tvar LogLuvEncoding = 3003;\n\tvar RGBM7Encoding = 3004;\n\tvar RGBM16Encoding = 3005;\n\tvar RGBDEncoding = 3006;\n\tvar BasicDepthPacking = 3200;\n\tvar RGBADepthPacking = 3201;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar _Math = {\n\n\t\tDEG2RAD: Math.PI / 180,\n\t\tRAD2DEG: 180 / Math.PI,\n\n\t\tgenerateUUID: function () {\n\n\t\t\t// http://www.broofa.com/Tools/Math.uuid.htm\n\n\t\t\tvar chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split( '' );\n\t\t\tvar uuid = new Array( 36 );\n\t\t\tvar rnd = 0, r;\n\n\t\t\treturn function generateUUID() {\n\n\t\t\t\tfor ( var i = 0; i < 36; i ++ ) {\n\n\t\t\t\t\tif ( i === 8 || i === 13 || i === 18 || i === 23 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '-';\n\n\t\t\t\t\t} else if ( i === 14 ) {\n\n\t\t\t\t\t\tuuid[ i ] = '4';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( rnd <= 0x02 ) rnd = 0x2000000 + ( Math.random() * 0x1000000 ) | 0;\n\t\t\t\t\t\tr = rnd & 0xf;\n\t\t\t\t\t\trnd = rnd >> 4;\n\t\t\t\t\t\tuuid[ i ] = chars[ ( i === 19 ) ? ( r & 0x3 ) | 0x8 : r ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn uuid.join( '' );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclamp: function ( value, min, max ) {\n\n\t\t\treturn Math.max( min, Math.min( max, value ) );\n\n\t\t},\n\n\t\t// compute euclidian modulo of m % n\n\t\t// https://en.wikipedia.org/wiki/Modulo_operation\n\n\t\teuclideanModulo: function ( n, m ) {\n\n\t\t\treturn ( ( n % m ) + m ) % m;\n\n\t\t},\n\n\t\t// Linear mapping from range to range \n\n\t\tmapLinear: function ( x, a1, a2, b1, b2 ) {\n\n\t\t\treturn b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );\n\n\t\t},\n\n\t\t// https://en.wikipedia.org/wiki/Linear_interpolation\n\n\t\tlerp: function ( x, y, t ) {\n\n\t\t\treturn ( 1 - t ) * x + t * y;\n\n\t\t},\n\n\t\t// http://en.wikipedia.org/wiki/Smoothstep\n\n\t\tsmoothstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * ( 3 - 2 * x );\n\n\t\t},\n\n\t\tsmootherstep: function ( x, min, max ) {\n\n\t\t\tif ( x <= min ) return 0;\n\t\t\tif ( x >= max ) return 1;\n\n\t\t\tx = ( x - min ) / ( max - min );\n\n\t\t\treturn x * x * x * ( x * ( x * 6 - 15 ) + 10 );\n\n\t\t},\n\n\t\t// Random integer from interval\n\n\t\trandInt: function ( low, high ) {\n\n\t\t\treturn low + Math.floor( Math.random() * ( high - low + 1 ) );\n\n\t\t},\n\n\t\t// Random float from interval\n\n\t\trandFloat: function ( low, high ) {\n\n\t\t\treturn low + Math.random() * ( high - low );\n\n\t\t},\n\n\t\t// Random float from <-range/2, range/2> interval\n\n\t\trandFloatSpread: function ( range ) {\n\n\t\t\treturn range * ( 0.5 - Math.random() );\n\n\t\t},\n\n\t\tdegToRad: function ( degrees ) {\n\n\t\t\treturn degrees * _Math.DEG2RAD;\n\n\t\t},\n\n\t\tradToDeg: function ( radians ) {\n\n\t\t\treturn radians * _Math.RAD2DEG;\n\n\t\t},\n\n\t\tisPowerOfTwo: function ( value ) {\n\n\t\t\treturn ( value & ( value - 1 ) ) === 0 && value !== 0;\n\n\t\t},\n\n\t\tnearestPowerOfTwo: function ( value ) {\n\n\t\t\treturn Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );\n\n\t\t},\n\n\t\tnextPowerOfTwo: function ( value ) {\n\n\t\t\tvalue --;\n\t\t\tvalue |= value >> 1;\n\t\t\tvalue |= value >> 2;\n\t\t\tvalue |= value >> 4;\n\t\t\tvalue |= value >> 8;\n\t\t\tvalue |= value >> 16;\n\t\t\tvalue ++;\n\n\t\t\treturn value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author egraether / http://egraether.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tfunction Vector2( x, y ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\n\t}\n\n\tVector2.prototype = {\n\n\t\tconstructor: Vector2,\n\n\t\tisVector2: true,\n\n\t\tget width() {\n\n\t\t\treturn this.x;\n\n\t\t},\n\n\t\tset width( value ) {\n\n\t\t\tthis.x = value;\n\n\t\t},\n\n\t\tget height() {\n\n\t\t\treturn this.y;\n\n\t\t},\n\n\t\tset height( value ) {\n\n\t\t\tthis.y = value;\n\n\t\t},\n\n\t\t//\n\n\t\tset: function ( x, y ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v ) {\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector2();\n\t\t\t\t\tmax = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y );\n\n\t\t},\n\n\t\tlengthManhattan: function() {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tangle: function () {\n\n\t\t\t// computes the angle in radians with respect to the positive x-axis\n\n\t\t\tvar angle = Math.atan2( this.y, this.x );\n\n\t\t\tif ( angle < 0 ) angle += 2 * Math.PI;\n\n\t\t\treturn angle;\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y;\n\t\t\treturn dx * dx + dy * dy;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateAround: function ( center, angle ) {\n\n\t\t\tvar c = Math.cos( angle ), s = Math.sin( angle );\n\n\t\t\tvar x = this.x - center.x;\n\t\t\tvar y = this.y - center.y;\n\n\t\t\tthis.x = x * c - y * s + center.x;\n\t\t\tthis.y = x * s + y * c + center.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t */\n\n\tvar textureId = 0;\n\n\tfunction Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\tObject.defineProperty( this, 'id', { value: textureId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\n\t\tthis.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;\n\t\tthis.mipmaps = [];\n\n\t\tthis.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;\n\n\t\tthis.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;\n\t\tthis.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : LinearFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;\n\n\t\tthis.anisotropy = anisotropy !== undefined ? anisotropy : 1;\n\n\t\tthis.format = format !== undefined ? format : RGBAFormat;\n\t\tthis.type = type !== undefined ? type : UnsignedByteType;\n\n\t\tthis.offset = new Vector2( 0, 0 );\n\t\tthis.repeat = new Vector2( 1, 1 );\n\n\t\tthis.generateMipmaps = true;\n\t\tthis.premultiplyAlpha = false;\n\t\tthis.flipY = true;\n\t\tthis.unpackAlignment = 4;\t// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)\n\n\n\t\t// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.\n\t\t//\n\t\t// Also changing the encoding after already used by a Material will not automatically make the Material\n\t\t// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.\n\t\tthis.encoding = encoding !== undefined ? encoding : LinearEncoding;\n\n\t\tthis.version = 0;\n\t\tthis.onUpdate = null;\n\n\t}\n\n\tTexture.DEFAULT_IMAGE = undefined;\n\tTexture.DEFAULT_MAPPING = UVMapping;\n\n\tTexture.prototype = {\n\n\t\tconstructor: Texture,\n\n\t\tisTexture: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.image = source.image;\n\t\t\tthis.mipmaps = source.mipmaps.slice( 0 );\n\n\t\t\tthis.mapping = source.mapping;\n\n\t\t\tthis.wrapS = source.wrapS;\n\t\t\tthis.wrapT = source.wrapT;\n\n\t\t\tthis.magFilter = source.magFilter;\n\t\t\tthis.minFilter = source.minFilter;\n\n\t\t\tthis.anisotropy = source.anisotropy;\n\n\t\t\tthis.format = source.format;\n\t\t\tthis.type = source.type;\n\n\t\t\tthis.offset.copy( source.offset );\n\t\t\tthis.repeat.copy( source.repeat );\n\n\t\t\tthis.generateMipmaps = source.generateMipmaps;\n\t\t\tthis.premultiplyAlpha = source.premultiplyAlpha;\n\t\t\tthis.flipY = source.flipY;\n\t\t\tthis.unpackAlignment = source.unpackAlignment;\n\t\t\tthis.encoding = source.encoding;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tif ( meta.textures[ this.uuid ] !== undefined ) {\n\n\t\t\t\treturn meta.textures[ this.uuid ];\n\n\t\t\t}\n\n\t\t\tfunction getDataURL( image ) {\n\n\t\t\t\tvar canvas;\n\n\t\t\t\tif ( image.toDataURL !== undefined ) {\n\n\t\t\t\t\tcanvas = image;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tcanvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\t\tcanvas.width = image.width;\n\t\t\t\t\tcanvas.height = image.height;\n\n\t\t\t\t\tcanvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );\n\n\t\t\t\t}\n\n\t\t\t\tif ( canvas.width > 2048 || canvas.height > 2048 ) {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/jpeg', 0.6 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn canvas.toDataURL( 'image/png' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Texture',\n\t\t\t\t\tgenerator: 'Texture.toJSON'\n\t\t\t\t},\n\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tname: this.name,\n\n\t\t\t\tmapping: this.mapping,\n\n\t\t\t\trepeat: [ this.repeat.x, this.repeat.y ],\n\t\t\t\toffset: [ this.offset.x, this.offset.y ],\n\t\t\t\twrap: [ this.wrapS, this.wrapT ],\n\n\t\t\t\tminFilter: this.minFilter,\n\t\t\t\tmagFilter: this.magFilter,\n\t\t\t\tanisotropy: this.anisotropy,\n\n\t\t\t\tflipY: this.flipY\n\t\t\t};\n\n\t\t\tif ( this.image !== undefined ) {\n\n\t\t\t\t// TODO: Move to THREE.Image\n\n\t\t\t\tvar image = this.image;\n\n\t\t\t\tif ( image.uuid === undefined ) {\n\n\t\t\t\t\timage.uuid = _Math.generateUUID(); // UGH\n\n\t\t\t\t}\n\n\t\t\t\tif ( meta.images[ image.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.images[ image.uuid ] = {\n\t\t\t\t\t\tuuid: image.uuid,\n\t\t\t\t\t\turl: getDataURL( image )\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\toutput.image = image.uuid;\n\n\t\t\t}\n\n\t\t\tmeta.textures[ this.uuid ] = output;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t},\n\n\t\ttransformUv: function ( uv ) {\n\n\t\t\tif ( this.mapping !== UVMapping ) return;\n\n\t\t\tuv.multiply( this.repeat );\n\t\t\tuv.add( this.offset );\n\n\t\t\tif ( uv.x < 0 || uv.x > 1 ) {\n\n\t\t\t\tswitch ( this.wrapS ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.x = uv.x < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.x = Math.ceil( uv.x ) - uv.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.x = uv.x - Math.floor( uv.x );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( uv.y < 0 || uv.y > 1 ) {\n\n\t\t\t\tswitch ( this.wrapT ) {\n\n\t\t\t\t\tcase RepeatWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ClampToEdgeWrapping:\n\n\t\t\t\t\t\tuv.y = uv.y < 0 ? 0 : 1;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase MirroredRepeatWrapping:\n\n\t\t\t\t\t\tif ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {\n\n\t\t\t\t\t\t\tuv.y = Math.ceil( uv.y ) - uv.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tuv.y = uv.y - Math.floor( uv.y );\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.flipY ) {\n\n\t\t\t\tuv.y = 1 - uv.y;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tObject.assign( Texture.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector4( x, y, z, w ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\t\tthis.w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tVector4.prototype = {\n\n\t\tconstructor: Vector4,\n\n\t\tisVector4: true,\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\t\t\tthis.w = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( w ) {\n\n\t\t\tthis.w = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tcase 3: this.w = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tcase 3: return this.w;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z, this.w );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\t\t\tthis.w = ( v.w !== undefined ) ? v.w : 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\t\t\tthis.w += v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\t\t\tthis.w += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\t\t\tthis.w = a.w + b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\t\t\tthis.w += v.w * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\t\t\tthis.w -= v.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\t\t\tthis.w -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\t\t\tthis.w = a.w - b.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\t\t\t\tthis.w *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\t\t\t\tthis.w = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z, w = this.w;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;\n\t\t\tthis.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tsetAxisAngleFromQuaternion: function ( q ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\n\n\t\t\t// q is assumed to be normalized\n\n\t\t\tthis.w = 2 * Math.acos( q.w );\n\n\t\t\tvar s = Math.sqrt( 1 - q.w * q.w );\n\n\t\t\tif ( s < 0.0001 ) {\n\n\t\t\t\t this.x = 1;\n\t\t\t\t this.y = 0;\n\t\t\t\t this.z = 0;\n\n\t\t\t} else {\n\n\t\t\t\t this.x = q.x / s;\n\t\t\t\t this.y = q.y / s;\n\t\t\t\t this.z = q.z / s;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetAxisAngleFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar angle, x, y, z,\t\t// variables for result\n\t\t\t\tepsilon = 0.01,\t\t// margin to allow for rounding errors\n\t\t\t\tepsilon2 = 0.1,\t\t// margin to distinguish between 0 and 180 degrees\n\n\t\t\t\tte = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\tif ( ( Math.abs( m12 - m21 ) < epsilon ) &&\n\t\t\t ( Math.abs( m13 - m31 ) < epsilon ) &&\n\t\t\t ( Math.abs( m23 - m32 ) < epsilon ) ) {\n\n\t\t\t\t// singularity found\n\t\t\t\t// first check for identity matrix which must have +1 for all terms\n\t\t\t\t// in leading diagonal and zero in other terms\n\n\t\t\t\tif ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m13 + m31 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m23 + m32 ) < epsilon2 ) &&\n\t\t\t\t ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {\n\n\t\t\t\t\t// this singularity is identity matrix so angle = 0\n\n\t\t\t\t\tthis.set( 1, 0, 0, 0 );\n\n\t\t\t\t\treturn this; // zero angle, arbitrary axis\n\n\t\t\t\t}\n\n\t\t\t\t// otherwise this singularity is angle = 180\n\n\t\t\t\tangle = Math.PI;\n\n\t\t\t\tvar xx = ( m11 + 1 ) / 2;\n\t\t\t\tvar yy = ( m22 + 1 ) / 2;\n\t\t\t\tvar zz = ( m33 + 1 ) / 2;\n\t\t\t\tvar xy = ( m12 + m21 ) / 4;\n\t\t\t\tvar xz = ( m13 + m31 ) / 4;\n\t\t\t\tvar yz = ( m23 + m32 ) / 4;\n\n\t\t\t\tif ( ( xx > yy ) && ( xx > zz ) ) {\n\n\t\t\t\t\t// m11 is the largest diagonal term\n\n\t\t\t\t\tif ( xx < epsilon ) {\n\n\t\t\t\t\t\tx = 0;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tx = Math.sqrt( xx );\n\t\t\t\t\t\ty = xy / x;\n\t\t\t\t\t\tz = xz / x;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( yy > zz ) {\n\n\t\t\t\t\t// m22 is the largest diagonal term\n\n\t\t\t\t\tif ( yy < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0;\n\t\t\t\t\t\tz = 0.707106781;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ty = Math.sqrt( yy );\n\t\t\t\t\t\tx = xy / y;\n\t\t\t\t\t\tz = yz / y;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// m33 is the largest diagonal term so base result on this\n\n\t\t\t\t\tif ( zz < epsilon ) {\n\n\t\t\t\t\t\tx = 0.707106781;\n\t\t\t\t\t\ty = 0.707106781;\n\t\t\t\t\t\tz = 0;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tz = Math.sqrt( zz );\n\t\t\t\t\t\tx = xz / z;\n\t\t\t\t\t\ty = yz / z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.set( x, y, z, angle );\n\n\t\t\t\treturn this; // return 180 deg rotation\n\n\t\t\t}\n\n\t\t\t// as we have reached here there are no singularities so we can handle normally\n\n\t\t\tvar s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +\n\t\t\t ( m13 - m31 ) * ( m13 - m31 ) +\n\t\t\t ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize\n\n\t\t\tif ( Math.abs( s ) < 0.001 ) s = 1;\n\n\t\t\t// prevent divide by zero, should not happen if matrix is orthogonal and should be\n\t\t\t// caught by singularity test above, but I've left it in just in case\n\n\t\t\tthis.x = ( m32 - m23 ) / s;\n\t\t\tthis.y = ( m13 - m31 ) / s;\n\t\t\tthis.z = ( m21 - m12 ) / s;\n\t\t\tthis.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\t\t\tthis.w = Math.min( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\t\t\tthis.w = Math.max( this.w, v.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\t\t\tthis.w = Math.max( min.w, Math.min( max.w, this.w ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector4();\n\t\t\t\t\tmax = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\t\t\tthis.w = Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\t\t\tthis.w = Math.ceil( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\t\t\tthis.w = Math.round( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\t\t\tthis.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\t\t\tthis.w = - this.w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\t\t\tthis.w += ( v.w - this.w ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\t\t\tthis.w = array[ offset + 3 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\t\t\tarray[ offset + 3 ] = this.w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\t\t\tthis.w = attribute.getW( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author szimek / https://github.com/szimek/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Marius Kintel / https://github.com/kintel\n\t */\n\n\t/*\n\t In options, we can specify:\n\t * Texture parameters for an auto-generated target texture\n\t * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers\n\t*/\n\tfunction WebGLRenderTarget( width, height, options ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.scissor = new Vector4( 0, 0, width, height );\n\t\tthis.scissorTest = false;\n\n\t\tthis.viewport = new Vector4( 0, 0, width, height );\n\n\t\toptions = options || {};\n\n\t\tif ( options.minFilter === undefined ) options.minFilter = LinearFilter;\n\n\t\tthis.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );\n\n\t\tthis.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;\n\t\tthis.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;\n\t\tthis.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;\n\n\t}\n\n\tWebGLRenderTarget.prototype = {\n\n\t\tconstructor: WebGLRenderTarget,\n\n\t\tisWebGLRenderTarget: true,\n\n\t\tsetSize: function ( width, height ) {\n\n\t\t\tif ( this.width !== width || this.height !== height ) {\n\n\t\t\t\tthis.width = width;\n\t\t\t\tthis.height = height;\n\n\t\t\t\tthis.dispose();\n\n\t\t\t}\n\n\t\t\tthis.viewport.set( 0, 0, width, height );\n\t\t\tthis.scissor.set( 0, 0, width, height );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\tthis.viewport.copy( source.viewport );\n\n\t\t\tthis.texture = source.texture.clone();\n\n\t\t\tthis.depthBuffer = source.depthBuffer;\n\t\t\tthis.stencilBuffer = source.stencilBuffer;\n\t\t\tthis.depthTexture = source.depthTexture;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( WebGLRenderTarget.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com\n\t */\n\n\tfunction WebGLRenderTargetCube( width, height, options ) {\n\n\t\tWebGLRenderTarget.call( this, width, height, options );\n\n\t\tthis.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5\n\t\tthis.activeMipMapLevel = 0;\n\n\t}\n\n\tWebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype );\n\tWebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube;\n\n\tWebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true;\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Quaternion( x, y, z, w ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._w = ( w !== undefined ) ? w : 1;\n\n\t}\n\n\tQuaternion.prototype = {\n\n\t\tconstructor: Quaternion,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget w () {\n\n\t\t\treturn this._w;\n\n\t\t},\n\n\t\tset w ( value ) {\n\n\t\t\tthis._w = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, w ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._w = w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._w );\n\n\t\t},\n\n\t\tcopy: function ( quaternion ) {\n\n\t\t\tthis._x = quaternion.x;\n\t\t\tthis._y = quaternion.y;\n\t\t\tthis._z = quaternion.z;\n\t\t\tthis._w = quaternion.w;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromEuler: function ( euler, update ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tthrow new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\t// http://www.mathworks.com/matlabcentral/fileexchange/\n\t\t\t// \t20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/\n\t\t\t//\tcontent/SpinCalc.m\n\n\t\t\tvar c1 = Math.cos( euler._x / 2 );\n\t\t\tvar c2 = Math.cos( euler._y / 2 );\n\t\t\tvar c3 = Math.cos( euler._z / 2 );\n\t\t\tvar s1 = Math.sin( euler._x / 2 );\n\t\t\tvar s2 = Math.sin( euler._y / 2 );\n\t\t\tvar s3 = Math.sin( euler._z / 2 );\n\n\t\t\tvar order = euler.order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 + c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 + s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 - s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 - s1 * s2 * s3;\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._x = s1 * c2 * c3 - c1 * s2 * s3;\n\t\t\t\tthis._y = c1 * s2 * c3 - s1 * c2 * s3;\n\t\t\t\tthis._z = c1 * c2 * s3 + s1 * s2 * c3;\n\t\t\t\tthis._w = c1 * c2 * c3 + s1 * s2 * s3;\n\n\t\t\t}\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tvar halfAngle = angle / 2, s = Math.sin( halfAngle );\n\n\t\t\tthis._x = axis.x * s;\n\t\t\tthis._y = axis.y * s;\n\t\t\tthis._z = axis.z * s;\n\t\t\tthis._w = Math.cos( halfAngle );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m ) {\n\n\t\t\t// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements,\n\n\t\t\t\tm11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],\n\t\t\t\tm21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],\n\t\t\t\tm31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],\n\n\t\t\t\ttrace = m11 + m22 + m33,\n\t\t\t\ts;\n\n\t\t\tif ( trace > 0 ) {\n\n\t\t\t\ts = 0.5 / Math.sqrt( trace + 1.0 );\n\n\t\t\t\tthis._w = 0.25 / s;\n\t\t\t\tthis._x = ( m32 - m23 ) * s;\n\t\t\t\tthis._y = ( m13 - m31 ) * s;\n\t\t\t\tthis._z = ( m21 - m12 ) * s;\n\n\t\t\t} else if ( m11 > m22 && m11 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );\n\n\t\t\t\tthis._w = ( m32 - m23 ) / s;\n\t\t\t\tthis._x = 0.25 * s;\n\t\t\t\tthis._y = ( m12 + m21 ) / s;\n\t\t\t\tthis._z = ( m13 + m31 ) / s;\n\n\t\t\t} else if ( m22 > m33 ) {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );\n\n\t\t\t\tthis._w = ( m13 - m31 ) / s;\n\t\t\t\tthis._x = ( m12 + m21 ) / s;\n\t\t\t\tthis._y = 0.25 * s;\n\t\t\t\tthis._z = ( m23 + m32 ) / s;\n\n\t\t\t} else {\n\n\t\t\t\ts = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );\n\n\t\t\t\tthis._w = ( m21 - m12 ) / s;\n\t\t\t\tthis._x = ( m13 + m31 ) / s;\n\t\t\t\tthis._y = ( m23 + m32 ) / s;\n\t\t\t\tthis._z = 0.25 * s;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromUnitVectors: function () {\n\n\t\t\t// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n\n\t\t\t// assumes direction vectors vFrom and vTo are normalized\n\n\t\t\tvar v1, r;\n\n\t\t\tvar EPS = 0.000001;\n\n\t\t\treturn function setFromUnitVectors( vFrom, vTo ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tr = vFrom.dot( vTo ) + 1;\n\n\t\t\t\tif ( r < EPS ) {\n\n\t\t\t\t\tr = 0;\n\n\t\t\t\t\tif ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n\n\t\t\t\t\t\tv1.set( - vFrom.y, vFrom.x, 0 );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv1.set( 0, - vFrom.z, vFrom.y );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tv1.crossVectors( vFrom, vTo );\n\n\t\t\t\t}\n\n\t\t\t\tthis._x = v1.x;\n\t\t\t\tthis._y = v1.y;\n\t\t\t\tthis._z = v1.z;\n\t\t\t\tthis._w = r;\n\n\t\t\t\treturn this.normalize();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tinverse: function () {\n\n\t\t\treturn this.conjugate().normalize();\n\n\t\t},\n\n\t\tconjugate: function () {\n\n\t\t\tthis._x *= - 1;\n\t\t\tthis._y *= - 1;\n\t\t\tthis._z *= - 1;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tvar l = this.length();\n\n\t\t\tif ( l === 0 ) {\n\n\t\t\t\tthis._x = 0;\n\t\t\t\tthis._y = 0;\n\t\t\t\tthis._z = 0;\n\t\t\t\tthis._w = 1;\n\n\t\t\t} else {\n\n\t\t\t\tl = 1 / l;\n\n\t\t\t\tthis._x = this._x * l;\n\t\t\t\tthis._y = this._y * l;\n\t\t\t\tthis._z = this._z * l;\n\t\t\t\tthis._w = this._w * l;\n\n\t\t\t}\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( q, p ) {\n\n\t\t\tif ( p !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );\n\t\t\t\treturn this.multiplyQuaternions( q, p );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyQuaternions( this, q );\n\n\t\t},\n\n\t\tpremultiply: function ( q ) {\n\n\t\t\treturn this.multiplyQuaternions( q, this );\n\n\t\t},\n\n\t\tmultiplyQuaternions: function ( a, b ) {\n\n\t\t\t// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n\t\t\tvar qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;\n\t\t\tvar qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;\n\n\t\t\tthis._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n\t\t\tthis._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n\t\t\tthis._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n\t\t\tthis._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tslerp: function ( qb, t ) {\n\n\t\t\tif ( t === 0 ) return this;\n\t\t\tif ( t === 1 ) return this.copy( qb );\n\n\t\t\tvar x = this._x, y = this._y, z = this._z, w = this._w;\n\n\t\t\t// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n\t\t\tvar cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;\n\n\t\t\tif ( cosHalfTheta < 0 ) {\n\n\t\t\t\tthis._w = - qb._w;\n\t\t\t\tthis._x = - qb._x;\n\t\t\t\tthis._y = - qb._y;\n\t\t\t\tthis._z = - qb._z;\n\n\t\t\t\tcosHalfTheta = - cosHalfTheta;\n\n\t\t\t} else {\n\n\t\t\t\tthis.copy( qb );\n\n\t\t\t}\n\n\t\t\tif ( cosHalfTheta >= 1.0 ) {\n\n\t\t\t\tthis._w = w;\n\t\t\t\tthis._x = x;\n\t\t\t\tthis._y = y;\n\t\t\t\tthis._z = z;\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n\t\t\tif ( Math.abs( sinHalfTheta ) < 0.001 ) {\n\n\t\t\t\tthis._w = 0.5 * ( w + this._w );\n\t\t\t\tthis._x = 0.5 * ( x + this._x );\n\t\t\t\tthis._y = 0.5 * ( y + this._y );\n\t\t\t\tthis._z = 0.5 * ( z + this._z );\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );\n\t\t\tvar ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,\n\t\t\tratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n\t\t\tthis._w = ( w * ratioA + this._w * ratioB );\n\t\t\tthis._x = ( x * ratioA + this._x * ratioB );\n\t\t\tthis._y = ( y * ratioA + this._y * ratioB );\n\t\t\tthis._z = ( z * ratioA + this._z * ratioB );\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( quaternion ) {\n\n\t\t\treturn ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis._x = array[ offset ];\n\t\t\tthis._y = array[ offset + 1 ];\n\t\t\tthis._z = array[ offset + 2 ];\n\t\t\tthis._w = array[ offset + 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._w;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\tObject.assign( Quaternion, {\n\n\t\tslerp: function( qa, qb, qm, t ) {\n\n\t\t\treturn qm.copy( qa ).slerp( qb, t );\n\n\t\t},\n\n\t\tslerpFlat: function(\n\t\t\t\tdst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {\n\n\t\t\t// fuzz-free, array-based Quaternion SLERP operation\n\n\t\t\tvar x0 = src0[ srcOffset0 + 0 ],\n\t\t\t\ty0 = src0[ srcOffset0 + 1 ],\n\t\t\t\tz0 = src0[ srcOffset0 + 2 ],\n\t\t\t\tw0 = src0[ srcOffset0 + 3 ],\n\n\t\t\t\tx1 = src1[ srcOffset1 + 0 ],\n\t\t\t\ty1 = src1[ srcOffset1 + 1 ],\n\t\t\t\tz1 = src1[ srcOffset1 + 2 ],\n\t\t\t\tw1 = src1[ srcOffset1 + 3 ];\n\n\t\t\tif ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {\n\n\t\t\t\tvar s = 1 - t,\n\n\t\t\t\t\tcos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,\n\n\t\t\t\t\tdir = ( cos >= 0 ? 1 : - 1 ),\n\t\t\t\t\tsqrSin = 1 - cos * cos;\n\n\t\t\t\t// Skip the Slerp for tiny steps to avoid numeric problems:\n\t\t\t\tif ( sqrSin > Number.EPSILON ) {\n\n\t\t\t\t\tvar sin = Math.sqrt( sqrSin ),\n\t\t\t\t\t\tlen = Math.atan2( sin, cos * dir );\n\n\t\t\t\t\ts = Math.sin( s * len ) / sin;\n\t\t\t\t\tt = Math.sin( t * len ) / sin;\n\n\t\t\t\t}\n\n\t\t\t\tvar tDir = t * dir;\n\n\t\t\t\tx0 = x0 * s + x1 * tDir;\n\t\t\t\ty0 = y0 * s + y1 * tDir;\n\t\t\t\tz0 = z0 * s + z1 * tDir;\n\t\t\t\tw0 = w0 * s + w1 * tDir;\n\n\t\t\t\t// Normalize in case we just did a lerp:\n\t\t\t\tif ( s === 1 - t ) {\n\n\t\t\t\t\tvar f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );\n\n\t\t\t\t\tx0 *= f;\n\t\t\t\t\ty0 *= f;\n\t\t\t\t\tz0 *= f;\n\t\t\t\t\tw0 *= f;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tdst[ dstOffset ] = x0;\n\t\t\tdst[ dstOffset + 1 ] = y0;\n\t\t\tdst[ dstOffset + 2 ] = z0;\n\t\t\tdst[ dstOffset + 3 ] = w0;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author *kile / http://kile.stravaganza.org/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author egraether / http://egraether.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Vector3( x, y, z ) {\n\n\t\tthis.x = x || 0;\n\t\tthis.y = y || 0;\n\t\tthis.z = z || 0;\n\n\t}\n\n\tVector3.prototype = {\n\n\t\tconstructor: Vector3,\n\n\t\tisVector3: true,\n\n\t\tset: function ( x, y, z ) {\n\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.x = scalar;\n\t\t\tthis.y = scalar;\n\t\t\tthis.z = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetX: function ( x ) {\n\n\t\t\tthis.x = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( y ) {\n\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( z ) {\n\n\t\t\tthis.z = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponent: function ( index, value ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: this.x = value; break;\n\t\t\t\tcase 1: this.y = value; break;\n\t\t\t\tcase 2: this.z = value; break;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetComponent: function ( index ) {\n\n\t\t\tswitch ( index ) {\n\n\t\t\t\tcase 0: return this.x;\n\t\t\t\tcase 1: return this.y;\n\t\t\t\tcase 2: return this.z;\n\t\t\t\tdefault: throw new Error( 'index is out of range: ' + index );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.x, this.y, this.z );\n\n\t\t},\n\n\t\tcopy: function ( v ) {\n\n\t\t\tthis.x = v.x;\n\t\t\tthis.y = v.y;\n\t\t\tthis.z = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );\n\t\t\t\treturn this.addVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x += v.x;\n\t\t\tthis.y += v.y;\n\t\t\tthis.z += v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.x += s;\n\t\t\tthis.y += s;\n\t\t\tthis.z += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x + b.x;\n\t\t\tthis.y = a.y + b.y;\n\t\t\tthis.z = a.z + b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScaledVector: function ( v, s ) {\n\n\t\t\tthis.x += v.x * s;\n\t\t\tthis.y += v.y * s;\n\t\t\tthis.z += v.z * s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );\n\t\t\t\treturn this.subVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x -= v.x;\n\t\t\tthis.y -= v.y;\n\t\t\tthis.z -= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubScalar: function ( s ) {\n\n\t\t\tthis.x -= s;\n\t\t\tthis.y -= s;\n\t\t\tthis.z -= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsubVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x - b.x;\n\t\t\tthis.y = a.y - b.y;\n\t\t\tthis.z = a.z - b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );\n\t\t\t\treturn this.multiplyVectors( v, w );\n\n\t\t\t}\n\n\t\t\tthis.x *= v.x;\n\t\t\tthis.y *= v.y;\n\t\t\tthis.z *= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( scalar ) {\n\n\t\t\tif ( isFinite( scalar ) ) {\n\n\t\t\t\tthis.x *= scalar;\n\t\t\t\tthis.y *= scalar;\n\t\t\t\tthis.z *= scalar;\n\n\t\t\t} else {\n\n\t\t\t\tthis.x = 0;\n\t\t\t\tthis.y = 0;\n\t\t\t\tthis.z = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyVectors: function ( a, b ) {\n\n\t\t\tthis.x = a.x * b.x;\n\t\t\tthis.y = a.y * b.y;\n\t\t\tthis.z = a.z * b.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyEuler: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyEuler( euler ) {\n\n\t\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\t\tconsole.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromEuler( euler ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyAxisAngle: function () {\n\n\t\t\tvar quaternion;\n\n\t\t\treturn function applyAxisAngle( axis, angle ) {\n\n\t\t\t\tif ( quaternion === undefined ) quaternion = new Quaternion();\n\n\t\t\t\treturn this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix3: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( m ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ];\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ];\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];\n\t\t\tvar w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];\n\n\t\t\treturn this.divideScalar( w );\n\n\t\t},\n\n\t\tapplyQuaternion: function ( q ) {\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar qx = q.x, qy = q.y, qz = q.z, qw = q.w;\n\n\t\t\t// calculate quat * vector\n\n\t\t\tvar ix = qw * x + qy * z - qz * y;\n\t\t\tvar iy = qw * y + qz * x - qx * z;\n\t\t\tvar iz = qw * z + qx * y - qy * x;\n\t\t\tvar iw = - qx * x - qy * y - qz * z;\n\n\t\t\t// calculate result * inverse quat\n\n\t\t\tthis.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n\t\t\tthis.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n\t\t\tthis.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function project( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.projectionMatrix, matrix.getInverse( camera.matrixWorld ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tunproject: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function unproject( camera ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.multiplyMatrices( camera.matrixWorld, matrix.getInverse( camera.projectionMatrix ) );\n\t\t\t\treturn this.applyMatrix4( matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttransformDirection: function ( m ) {\n\n\t\t\t// input: THREE.Matrix4 affine matrix\n\t\t\t// vector interpreted as a direction\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\t\t\tvar e = m.elements;\n\n\t\t\tthis.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;\n\t\t\tthis.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;\n\t\t\tthis.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;\n\n\t\t\treturn this.normalize();\n\n\t\t},\n\n\t\tdivide: function ( v ) {\n\n\t\t\tthis.x /= v.x;\n\t\t\tthis.y /= v.y;\n\t\t\tthis.z /= v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdivideScalar: function ( scalar ) {\n\n\t\t\treturn this.multiplyScalar( 1 / scalar );\n\n\t\t},\n\n\t\tmin: function ( v ) {\n\n\t\t\tthis.x = Math.min( this.x, v.x );\n\t\t\tthis.y = Math.min( this.y, v.y );\n\t\t\tthis.z = Math.min( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmax: function ( v ) {\n\n\t\t\tthis.x = Math.max( this.x, v.x );\n\t\t\tthis.y = Math.max( this.y, v.y );\n\t\t\tthis.z = Math.max( this.z, v.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclamp: function ( min, max ) {\n\n\t\t\t// This function assumes min < max, if this assumption isn't true it will not operate correctly\n\n\t\t\tthis.x = Math.max( min.x, Math.min( max.x, this.x ) );\n\t\t\tthis.y = Math.max( min.y, Math.min( max.y, this.y ) );\n\t\t\tthis.z = Math.max( min.z, Math.min( max.z, this.z ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclampScalar: function () {\n\n\t\t\tvar min, max;\n\n\t\t\treturn function clampScalar( minVal, maxVal ) {\n\n\t\t\t\tif ( min === undefined ) {\n\n\t\t\t\t\tmin = new Vector3();\n\t\t\t\t\tmax = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tmin.set( minVal, minVal, minVal );\n\t\t\t\tmax.set( maxVal, maxVal, maxVal );\n\n\t\t\t\treturn this.clamp( min, max );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclampLength: function ( min, max ) {\n\n\t\t\tvar length = this.length();\n\n\t\t\treturn this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );\n\n\t\t},\n\n\t\tfloor: function () {\n\n\t\t\tthis.x = Math.floor( this.x );\n\t\t\tthis.y = Math.floor( this.y );\n\t\t\tthis.z = Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tceil: function () {\n\n\t\t\tthis.x = Math.ceil( this.x );\n\t\t\tthis.y = Math.ceil( this.y );\n\t\t\tthis.z = Math.ceil( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tround: function () {\n\n\t\t\tthis.x = Math.round( this.x );\n\t\t\tthis.y = Math.round( this.y );\n\t\t\tthis.z = Math.round( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\troundToZero: function () {\n\n\t\t\tthis.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );\n\t\t\tthis.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );\n\t\t\tthis.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.x = - this.x;\n\t\t\tthis.y = - this.y;\n\t\t\tthis.z = - this.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdot: function ( v ) {\n\n\t\t\treturn this.x * v.x + this.y * v.y + this.z * v.z;\n\n\t\t},\n\n\t\tlengthSq: function () {\n\n\t\t\treturn this.x * this.x + this.y * this.y + this.z * this.z;\n\n\t\t},\n\n\t\tlength: function () {\n\n\t\t\treturn Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n\n\t\t},\n\n\t\tlengthManhattan: function () {\n\n\t\t\treturn Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\treturn this.divideScalar( this.length() );\n\n\t\t},\n\n\t\tsetLength: function ( length ) {\n\n\t\t\treturn this.multiplyScalar( length / this.length() );\n\n\t\t},\n\n\t\tlerp: function ( v, alpha ) {\n\n\t\t\tthis.x += ( v.x - this.x ) * alpha;\n\t\t\tthis.y += ( v.y - this.y ) * alpha;\n\t\t\tthis.z += ( v.z - this.z ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerpVectors: function ( v1, v2, alpha ) {\n\n\t\t\treturn this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 );\n\n\t\t},\n\n\t\tcross: function ( v, w ) {\n\n\t\t\tif ( w !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );\n\t\t\t\treturn this.crossVectors( v, w );\n\n\t\t\t}\n\n\t\t\tvar x = this.x, y = this.y, z = this.z;\n\n\t\t\tthis.x = y * v.z - z * v.y;\n\t\t\tthis.y = z * v.x - x * v.z;\n\t\t\tthis.z = x * v.y - y * v.x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossVectors: function ( a, b ) {\n\n\t\t\tvar ax = a.x, ay = a.y, az = a.z;\n\t\t\tvar bx = b.x, by = b.y, bz = b.z;\n\n\t\t\tthis.x = ay * bz - az * by;\n\t\t\tthis.y = az * bx - ax * bz;\n\t\t\tthis.z = ax * by - ay * bx;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tprojectOnVector: function ( vector ) {\n\n\t\t\tvar scalar = vector.dot( this ) / vector.lengthSq();\n\n\t\t\treturn this.copy( vector ).multiplyScalar( scalar );\n\n\t\t},\n\n\t\tprojectOnPlane: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function projectOnPlane( planeNormal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tv1.copy( this ).projectOnVector( planeNormal );\n\n\t\t\t\treturn this.sub( v1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\treflect: function () {\n\n\t\t\t// reflect incident vector off plane orthogonal to normal\n\t\t\t// normal is assumed to have unit length\n\n\t\t\tvar v1;\n\n\t\t\treturn function reflect( normal ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\treturn this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tangleTo: function ( v ) {\n\n\t\t\tvar theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) );\n\n\t\t\t// clamp, to handle numerical problems\n\n\t\t\treturn Math.acos( _Math.clamp( theta, - 1, 1 ) );\n\n\t\t},\n\n\t\tdistanceTo: function ( v ) {\n\n\t\t\treturn Math.sqrt( this.distanceToSquared( v ) );\n\n\t\t},\n\n\t\tdistanceToSquared: function ( v ) {\n\n\t\t\tvar dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;\n\n\t\t\treturn dx * dx + dy * dy + dz * dz;\n\n\t\t},\n\n\t\tdistanceToManhattan: function ( v ) {\n\n\t\t\treturn Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );\n\n\t\t},\n\n\t\tsetFromSpherical: function( s ) {\n\n\t\t\tvar sinPhiRadius = Math.sin( s.phi ) * s.radius;\n\n\t\t\tthis.x = sinPhiRadius * Math.sin( s.theta );\n\t\t\tthis.y = Math.cos( s.phi ) * s.radius;\n\t\t\tthis.z = sinPhiRadius * Math.cos( s.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCylindrical: function( c ) {\n\n\t\t\tthis.x = c.radius * Math.sin( c.theta );\n\t\t\tthis.y = c.y;\n\t\t\tthis.z = c.radius * Math.cos( c.theta );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixPosition: function ( m ) {\n\n\t\t\treturn this.setFromMatrixColumn( m, 3 );\n\n\t\t},\n\n\t\tsetFromMatrixScale: function ( m ) {\n\n\t\t\tvar sx = this.setFromMatrixColumn( m, 0 ).length();\n\t\t\tvar sy = this.setFromMatrixColumn( m, 1 ).length();\n\t\t\tvar sz = this.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\tthis.x = sx;\n\t\t\tthis.y = sy;\n\t\t\tthis.z = sz;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrixColumn: function ( m, index ) {\n\n\t\t\tif ( typeof m === 'number' ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' );\n\t\t\t\tvar temp = m;\n\t\t\t\tm = index;\n\t\t\t\tindex = temp;\n\n\t\t\t}\n\n\t\t\treturn this.fromArray( m.elements, index * 4 );\n\n\t\t},\n\n\t\tequals: function ( v ) {\n\n\t\t\treturn ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.x = array[ offset ];\n\t\t\tthis.y = array[ offset + 1 ];\n\t\t\tthis.z = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.x;\n\t\t\tarray[ offset + 1 ] = this.y;\n\t\t\tarray[ offset + 2 ] = this.z;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tfromBufferAttribute: function ( attribute, index, offset ) {\n\n\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );\n\n\t\t\t}\n\n\t\t\tthis.x = attribute.getX( index );\n\t\t\tthis.y = attribute.getY( index );\n\t\t\tthis.z = attribute.getZ( index );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author philogb / http://blog.thejit.org/\n\t * @author jordi_ros / http://plattsoft.com\n\t * @author D1plo1d / http://github.com/D1plo1d\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author timknip / http://www.floorplanner.com/\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Matrix4() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0, 0,\n\t\t\t0, 1, 0, 0,\n\t\t\t0, 0, 1, 0,\n\t\t\t0, 0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix4.prototype = {\n\n\t\tconstructor: Matrix4,\n\n\t\tisMatrix4: true,\n\n\t\tset: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;\n\t\t\tte[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;\n\t\t\tte[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;\n\t\t\tte[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, 1, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new Matrix4().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tthis.elements.set( m.elements );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyPosition: function ( m ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = m.elements;\n\n\t\t\tte[ 12 ] = me[ 12 ];\n\t\t\tte[ 13 ] = me[ 13 ];\n\t\t\tte[ 14 ] = me[ 14 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\txAxis.setFromMatrixColumn( this, 0 );\n\t\t\tyAxis.setFromMatrixColumn( this, 1 );\n\t\t\tzAxis.setFromMatrixColumn( this, 2 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeBasis: function ( xAxis, yAxis, zAxis ) {\n\n\t\t\tthis.set(\n\t\t\t\txAxis.x, yAxis.x, zAxis.x, 0,\n\t\t\t\txAxis.y, yAxis.y, zAxis.y, 0,\n\t\t\t\txAxis.z, yAxis.z, zAxis.z, 0,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\textractRotation: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function extractRotation( m ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tvar te = this.elements;\n\t\t\t\tvar me = m.elements;\n\n\t\t\t\tvar scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length();\n\t\t\t\tvar scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length();\n\t\t\t\tvar scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length();\n\n\t\t\t\tte[ 0 ] = me[ 0 ] * scaleX;\n\t\t\t\tte[ 1 ] = me[ 1 ] * scaleX;\n\t\t\t\tte[ 2 ] = me[ 2 ] * scaleX;\n\n\t\t\t\tte[ 4 ] = me[ 4 ] * scaleY;\n\t\t\t\tte[ 5 ] = me[ 5 ] * scaleY;\n\t\t\t\tte[ 6 ] = me[ 6 ] * scaleY;\n\n\t\t\t\tte[ 8 ] = me[ 8 ] * scaleZ;\n\t\t\t\tte[ 9 ] = me[ 9 ] * scaleZ;\n\t\t\t\tte[ 10 ] = me[ 10 ] * scaleZ;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakeRotationFromEuler: function ( euler ) {\n\n\t\t\tif ( (euler && euler.isEuler) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = euler.x, y = euler.y, z = euler.z;\n\t\t\tvar a = Math.cos( x ), b = Math.sin( x );\n\t\t\tvar c = Math.cos( y ), d = Math.sin( y );\n\t\t\tvar e = Math.cos( z ), f = Math.sin( z );\n\n\t\t\tif ( euler.order === 'XYZ' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - c * f;\n\t\t\t\tte[ 8 ] = d;\n\n\t\t\t\tte[ 1 ] = af + be * d;\n\t\t\t\tte[ 5 ] = ae - bf * d;\n\t\t\t\tte[ 9 ] = - b * c;\n\n\t\t\t\tte[ 2 ] = bf - ae * d;\n\t\t\t\tte[ 6 ] = be + af * d;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YXZ' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce + df * b;\n\t\t\t\tte[ 4 ] = de * b - cf;\n\t\t\t\tte[ 8 ] = a * d;\n\n\t\t\t\tte[ 1 ] = a * f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b;\n\n\t\t\t\tte[ 2 ] = cf * b - de;\n\t\t\t\tte[ 6 ] = df + ce * b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZXY' ) {\n\n\t\t\t\tvar ce = c * e, cf = c * f, de = d * e, df = d * f;\n\n\t\t\t\tte[ 0 ] = ce - df * b;\n\t\t\t\tte[ 4 ] = - a * f;\n\t\t\t\tte[ 8 ] = de + cf * b;\n\n\t\t\t\tte[ 1 ] = cf + de * b;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = df - ce * b;\n\n\t\t\t\tte[ 2 ] = - a * d;\n\t\t\t\tte[ 6 ] = b;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'ZYX' ) {\n\n\t\t\t\tvar ae = a * e, af = a * f, be = b * e, bf = b * f;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = be * d - af;\n\t\t\t\tte[ 8 ] = ae * d + bf;\n\n\t\t\t\tte[ 1 ] = c * f;\n\t\t\t\tte[ 5 ] = bf * d + ae;\n\t\t\t\tte[ 9 ] = af * d - be;\n\n\t\t\t\tte[ 2 ] = - d;\n\t\t\t\tte[ 6 ] = b * c;\n\t\t\t\tte[ 10 ] = a * c;\n\n\t\t\t} else if ( euler.order === 'YZX' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = bd - ac * f;\n\t\t\t\tte[ 8 ] = bc * f + ad;\n\n\t\t\t\tte[ 1 ] = f;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = - b * e;\n\n\t\t\t\tte[ 2 ] = - d * e;\n\t\t\t\tte[ 6 ] = ad * f + bc;\n\t\t\t\tte[ 10 ] = ac - bd * f;\n\n\t\t\t} else if ( euler.order === 'XZY' ) {\n\n\t\t\t\tvar ac = a * c, ad = a * d, bc = b * c, bd = b * d;\n\n\t\t\t\tte[ 0 ] = c * e;\n\t\t\t\tte[ 4 ] = - f;\n\t\t\t\tte[ 8 ] = d * e;\n\n\t\t\t\tte[ 1 ] = ac * f + bd;\n\t\t\t\tte[ 5 ] = a * e;\n\t\t\t\tte[ 9 ] = ad * f - bc;\n\n\t\t\t\tte[ 2 ] = bc * f - ad;\n\t\t\t\tte[ 6 ] = b * e;\n\t\t\t\tte[ 10 ] = bd * f + ac;\n\n\t\t\t}\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationFromQuaternion: function ( q ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar x = q.x, y = q.y, z = q.z, w = q.w;\n\t\t\tvar x2 = x + x, y2 = y + y, z2 = z + z;\n\t\t\tvar xx = x * x2, xy = x * y2, xz = x * z2;\n\t\t\tvar yy = y * y2, yz = y * z2, zz = z * z2;\n\t\t\tvar wx = w * x2, wy = w * y2, wz = w * z2;\n\n\t\t\tte[ 0 ] = 1 - ( yy + zz );\n\t\t\tte[ 4 ] = xy - wz;\n\t\t\tte[ 8 ] = xz + wy;\n\n\t\t\tte[ 1 ] = xy + wz;\n\t\t\tte[ 5 ] = 1 - ( xx + zz );\n\t\t\tte[ 9 ] = yz - wx;\n\n\t\t\tte[ 2 ] = xz - wy;\n\t\t\tte[ 6 ] = yz + wx;\n\t\t\tte[ 10 ] = 1 - ( xx + yy );\n\n\t\t\t// last column\n\t\t\tte[ 3 ] = 0;\n\t\t\tte[ 7 ] = 0;\n\t\t\tte[ 11 ] = 0;\n\n\t\t\t// bottom row\n\t\t\tte[ 12 ] = 0;\n\t\t\tte[ 13 ] = 0;\n\t\t\tte[ 14 ] = 0;\n\t\t\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlookAt: function () {\n\n\t\t\tvar x, y, z;\n\n\t\t\treturn function lookAt( eye, target, up ) {\n\n\t\t\t\tif ( x === undefined ) {\n\n\t\t\t\t\tx = new Vector3();\n\t\t\t\t\ty = new Vector3();\n\t\t\t\t\tz = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tz.subVectors( eye, target ).normalize();\n\n\t\t\t\tif ( z.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z = 1;\n\n\t\t\t\t}\n\n\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\tif ( x.lengthSq() === 0 ) {\n\n\t\t\t\t\tz.z += 0.0001;\n\t\t\t\t\tx.crossVectors( up, z ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\ty.crossVectors( z, x );\n\n\n\t\t\t\tte[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;\n\t\t\t\tte[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;\n\t\t\t\tte[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiply: function ( m, n ) {\n\n\t\t\tif ( n !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );\n\t\t\t\treturn this.multiplyMatrices( m, n );\n\n\t\t\t}\n\n\t\t\treturn this.multiplyMatrices( this, m );\n\n\t\t},\n\n\t\tpremultiply: function ( m ) {\n\n\t\t\treturn this.multiplyMatrices( m, this );\n\n\t\t},\n\n\t\tmultiplyMatrices: function ( a, b ) {\n\n\t\t\tvar ae = a.elements;\n\t\t\tvar be = b.elements;\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];\n\t\t\tvar a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];\n\t\t\tvar a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];\n\t\t\tvar a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];\n\n\t\t\tvar b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];\n\t\t\tvar b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];\n\t\t\tvar b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];\n\t\t\tvar b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];\n\n\t\t\tte[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n\t\t\tte[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n\t\t\tte[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n\t\t\tte[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n\n\t\t\tte[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n\t\t\tte[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n\t\t\tte[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n\t\t\tte[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n\n\t\t\tte[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n\t\t\tte[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n\t\t\tte[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n\t\t\tte[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n\n\t\t\tte[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n\t\t\tte[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n\t\t\tte[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n\t\t\tte[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyToArray: function ( a, b, r ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tthis.multiplyMatrices( a, b );\n\n\t\t\tr[ 0 ] = te[ 0 ]; r[ 1 ] = te[ 1 ]; r[ 2 ] = te[ 2 ]; r[ 3 ] = te[ 3 ];\n\t\t\tr[ 4 ] = te[ 4 ]; r[ 5 ] = te[ 5 ]; r[ 6 ] = te[ 6 ]; r[ 7 ] = te[ 7 ];\n\t\t\tr[ 8 ] = te[ 8 ]; r[ 9 ] = te[ 9 ]; r[ 10 ] = te[ 10 ]; r[ 11 ] = te[ 11 ];\n\t\t\tr[ 12 ] = te[ 12 ]; r[ 13 ] = te[ 13 ]; r[ 14 ] = te[ 14 ]; r[ 15 ] = te[ 15 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;\n\t\t\tte[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix4( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];\n\t\t\tvar n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];\n\t\t\tvar n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];\n\t\t\tvar n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];\n\n\t\t\t//TODO: make this more efficient\n\t\t\t//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )\n\n\t\t\treturn (\n\t\t\t\tn41 * (\n\t\t\t\t\t+ n14 * n23 * n32\n\t\t\t\t\t - n13 * n24 * n32\n\t\t\t\t\t - n14 * n22 * n33\n\t\t\t\t\t + n12 * n24 * n33\n\t\t\t\t\t + n13 * n22 * n34\n\t\t\t\t\t - n12 * n23 * n34\n\t\t\t\t) +\n\t\t\t\tn42 * (\n\t\t\t\t\t+ n11 * n23 * n34\n\t\t\t\t\t - n11 * n24 * n33\n\t\t\t\t\t + n14 * n21 * n33\n\t\t\t\t\t - n13 * n21 * n34\n\t\t\t\t\t + n13 * n24 * n31\n\t\t\t\t\t - n14 * n23 * n31\n\t\t\t\t) +\n\t\t\t\tn43 * (\n\t\t\t\t\t+ n11 * n24 * n32\n\t\t\t\t\t - n11 * n22 * n34\n\t\t\t\t\t - n14 * n21 * n32\n\t\t\t\t\t + n12 * n21 * n34\n\t\t\t\t\t + n14 * n22 * n31\n\t\t\t\t\t - n12 * n24 * n31\n\t\t\t\t) +\n\t\t\t\tn44 * (\n\t\t\t\t\t- n13 * n22 * n31\n\t\t\t\t\t - n11 * n23 * n32\n\t\t\t\t\t + n11 * n22 * n33\n\t\t\t\t\t + n13 * n21 * n32\n\t\t\t\t\t - n12 * n21 * n33\n\t\t\t\t\t + n12 * n23 * n31\n\t\t\t\t)\n\n\t\t\t);\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar tmp;\n\n\t\t\ttmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;\n\t\t\ttmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;\n\t\t\ttmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;\n\n\t\t\ttmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;\n\t\t\ttmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;\n\t\t\ttmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPosition: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 12 ] = v.x;\n\t\t\tte[ 13 ] = v.y;\n\t\t\tte[ 14 ] = v.z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetInverse: function ( m, throwOnDegenerate ) {\n\n\t\t\t// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n\t\t\tvar te = this.elements,\n\t\t\t\tme = m.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],\n\t\t\t\tn12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],\n\t\t\t\tn13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],\n\t\t\t\tn14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],\n\n\t\t\t\tt11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,\n\t\t\t\tt12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,\n\t\t\t\tt13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,\n\t\t\t\tt14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;\n\n\t\t\tvar det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;\n\t\t\tte[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;\n\t\t\tte[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 4 ] = t12 * detInv;\n\t\t\tte[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;\n\t\t\tte[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;\n\t\t\tte[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;\n\n\t\t\tte[ 8 ] = t13 * detInv;\n\t\t\tte[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;\n\t\t\tte[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;\n\t\t\tte[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;\n\n\t\t\tte[ 12 ] = t14 * detInv;\n\t\t\tte[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;\n\t\t\tte[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;\n\t\t\tte[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tscale: function ( v ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = v.x, y = v.y, z = v.z;\n\n\t\t\tte[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;\n\t\t\tte[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;\n\t\t\tte[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;\n\t\t\tte[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetMaxScaleOnAxis: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];\n\t\t\tvar scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];\n\t\t\tvar scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];\n\n\t\t\treturn Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );\n\n\t\t},\n\n\t\tmakeTranslation: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, x,\n\t\t\t\t0, 1, 0, y,\n\t\t\t\t0, 0, 1, z,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationX: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0, 0,\n\t\t\t\t0, c, - s, 0,\n\t\t\t\t0, s, c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationY: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\t c, 0, s, 0,\n\t\t\t\t 0, 1, 0, 0,\n\t\t\t\t- s, 0, c, 0,\n\t\t\t\t 0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationZ: function ( theta ) {\n\n\t\t\tvar c = Math.cos( theta ), s = Math.sin( theta );\n\n\t\t\tthis.set(\n\n\t\t\t\tc, - s, 0, 0,\n\t\t\t\ts, c, 0, 0,\n\t\t\t\t0, 0, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeRotationAxis: function ( axis, angle ) {\n\n\t\t\t// Based on http://www.gamedev.net/reference/articles/article1199.asp\n\n\t\t\tvar c = Math.cos( angle );\n\t\t\tvar s = Math.sin( angle );\n\t\t\tvar t = 1 - c;\n\t\t\tvar x = axis.x, y = axis.y, z = axis.z;\n\t\t\tvar tx = t * x, ty = t * y;\n\n\t\t\tthis.set(\n\n\t\t\t\ttx * x + c, tx * y - s * z, tx * z + s * y, 0,\n\t\t\t\ttx * y + s * z, ty * y + c, ty * z - s * x, 0,\n\t\t\t\ttx * z - s * y, ty * z + s * x, t * z * z + c, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\t return this;\n\n\t\t},\n\n\t\tmakeScale: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\tx, 0, 0, 0,\n\t\t\t\t0, y, 0, 0,\n\t\t\t\t0, 0, z, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeShear: function ( x, y, z ) {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, y, z, 0,\n\t\t\t\tx, 1, z, 0,\n\t\t\t\tx, y, 1, 0,\n\t\t\t\t0, 0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcompose: function ( position, quaternion, scale ) {\n\n\t\t\tthis.makeRotationFromQuaternion( quaternion );\n\t\t\tthis.scale( scale );\n\t\t\tthis.setPosition( position );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdecompose: function () {\n\n\t\t\tvar vector, matrix;\n\n\t\t\treturn function decompose( position, quaternion, scale ) {\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tvector = new Vector3();\n\t\t\t\t\tmatrix = new Matrix4();\n\n\t\t\t\t}\n\n\t\t\t\tvar te = this.elements;\n\n\t\t\t\tvar sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();\n\t\t\t\tvar sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();\n\t\t\t\tvar sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();\n\n\t\t\t\t// if determine is negative, we need to invert one scale\n\t\t\t\tvar det = this.determinant();\n\t\t\t\tif ( det < 0 ) {\n\n\t\t\t\t\tsx = - sx;\n\n\t\t\t\t}\n\n\t\t\t\tposition.x = te[ 12 ];\n\t\t\t\tposition.y = te[ 13 ];\n\t\t\t\tposition.z = te[ 14 ];\n\n\t\t\t\t// scale the rotation part\n\n\t\t\t\tmatrix.elements.set( this.elements ); // at this point matrix is incomplete so we can't use .copy()\n\n\t\t\t\tvar invSX = 1 / sx;\n\t\t\t\tvar invSY = 1 / sy;\n\t\t\t\tvar invSZ = 1 / sz;\n\n\t\t\t\tmatrix.elements[ 0 ] *= invSX;\n\t\t\t\tmatrix.elements[ 1 ] *= invSX;\n\t\t\t\tmatrix.elements[ 2 ] *= invSX;\n\n\t\t\t\tmatrix.elements[ 4 ] *= invSY;\n\t\t\t\tmatrix.elements[ 5 ] *= invSY;\n\t\t\t\tmatrix.elements[ 6 ] *= invSY;\n\n\t\t\t\tmatrix.elements[ 8 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 9 ] *= invSZ;\n\t\t\t\tmatrix.elements[ 10 ] *= invSZ;\n\n\t\t\t\tquaternion.setFromRotationMatrix( matrix );\n\n\t\t\t\tscale.x = sx;\n\t\t\t\tscale.y = sy;\n\t\t\t\tscale.z = sz;\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmakePerspective: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tif ( far === undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );\n\n\t\t\t}\n\n\t\t\tvar te = this.elements;\n\t\t\tvar x = 2 * near / ( right - left );\n\t\t\tvar y = 2 * near / ( top - bottom );\n\n\t\t\tvar a = ( right + left ) / ( right - left );\n\t\t\tvar b = ( top + bottom ) / ( top - bottom );\n\t\t\tvar c = - ( far + near ) / ( far - near );\n\t\t\tvar d = - 2 * far * near / ( far - near );\n\n\t\t\tte[ 0 ] = x;\tte[ 4 ] = 0;\tte[ 8 ] = a;\tte[ 12 ] = 0;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = y;\tte[ 9 ] = b;\tte[ 13 ] = 0;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = c;\tte[ 14 ] = d;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = - 1;\tte[ 15 ] = 0;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeOrthographic: function ( left, right, top, bottom, near, far ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar w = 1.0 / ( right - left );\n\t\t\tvar h = 1.0 / ( top - bottom );\n\t\t\tvar p = 1.0 / ( far - near );\n\n\t\t\tvar x = ( right + left ) * w;\n\t\t\tvar y = ( top + bottom ) * h;\n\t\t\tvar z = ( far + near ) * p;\n\n\t\t\tte[ 0 ] = 2 * w;\tte[ 4 ] = 0;\tte[ 8 ] = 0;\tte[ 12 ] = - x;\n\t\t\tte[ 1 ] = 0;\tte[ 5 ] = 2 * h;\tte[ 9 ] = 0;\tte[ 13 ] = - y;\n\t\t\tte[ 2 ] = 0;\tte[ 6 ] = 0;\tte[ 10 ] = - 2 * p;\tte[ 14 ] = - z;\n\t\t\tte[ 3 ] = 0;\tte[ 7 ] = 0;\tte[ 11 ] = 0;\tte[ 15 ] = 1;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( matrix ) {\n\n\t\t\tvar te = this.elements;\n\t\t\tvar me = matrix.elements;\n\n\t\t\tfor ( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tif ( te[ i ] !== me[ i ] ) return false;\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 16; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\t\t\tarray[ offset + 9 ] = te[ 9 ];\n\t\t\tarray[ offset + 10 ] = te[ 10 ];\n\t\t\tarray[ offset + 11 ] = te[ 11 ];\n\n\t\t\tarray[ offset + 12 ] = te[ 12 ];\n\t\t\tarray[ offset + 13 ] = te[ 13 ];\n\t\t\tarray[ offset + 14 ] = te[ 14 ];\n\t\t\tarray[ offset + 15 ] = te[ 15 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {\n\n\t\timages = images !== undefined ? images : [];\n\t\tmapping = mapping !== undefined ? mapping : CubeReflectionMapping;\n\n\t\tTexture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.flipY = false;\n\n\t}\n\n\tCubeTexture.prototype = Object.create( Texture.prototype );\n\tCubeTexture.prototype.constructor = CubeTexture;\n\n\tCubeTexture.prototype.isCubeTexture = true;\n\n\tObject.defineProperty( CubeTexture.prototype, 'images', {\n\n\t\tget: function () {\n\n\t\t\treturn this.image;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tthis.image = value;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t *\n\t * Uniforms of a program.\n\t * Those form a tree structure with a special top-level container for the root,\n\t * which you get by calling 'new WebGLUniforms( gl, program, renderer )'.\n\t *\n\t *\n\t * Properties of inner nodes including the top-level container:\n\t *\n\t * .seq - array of nested uniforms\n\t * .map - nested uniforms by name\n\t *\n\t *\n\t * Methods of all nodes except the top-level container:\n\t *\n\t * .setValue( gl, value, [renderer] )\n\t *\n\t * \t\tuploads a uniform value(s)\n\t * \tthe 'renderer' parameter is needed for sampler uniforms\n\t *\n\t *\n\t * Static methods of the top-level container (renderer factorizations):\n\t *\n\t * .upload( gl, seq, values, renderer )\n\t *\n\t * \t\tsets uniforms in 'seq' to 'values[id].value'\n\t *\n\t * .seqWithValue( seq, values ) : filteredSeq\n\t *\n\t * \t\tfilters 'seq' entries with corresponding entry in values\n\t *\n\t *\n\t * Methods of the top-level container (renderer factorizations):\n\t *\n\t * .setValue( gl, name, value )\n\t *\n\t * \t\tsets uniform with name 'name' to 'value'\n\t *\n\t * .set( gl, obj, prop )\n\t *\n\t * \t\tsets uniform from object and property with same name than uniform\n\t *\n\t * .setOptional( gl, obj, prop )\n\t *\n\t * \t\tlike .set for an optional property of the object\n\t *\n\t */\n\n\tvar emptyTexture = new Texture();\n\tvar emptyCubeTexture = new CubeTexture();\n\n\t// --- Base for inner nodes (including the root) ---\n\n\tfunction UniformContainer() {\n\n\t\tthis.seq = [];\n\t\tthis.map = {};\n\n\t}\n\n\t// --- Utilities ---\n\n\t// Array Caches (provide typed arrays for temporary by size)\n\n\tvar arrayCacheF32 = [];\n\tvar arrayCacheI32 = [];\n\n\t// Flattening for arrays of vectors and matrices\n\n\tfunction flatten( array, nBlocks, blockSize ) {\n\n\t\tvar firstElem = array[ 0 ];\n\n\t\tif ( firstElem <= 0 || firstElem > 0 ) return array;\n\t\t// unoptimized: ! isNaN( firstElem )\n\t\t// see http://jacksondunstan.com/articles/983\n\n\t\tvar n = nBlocks * blockSize,\n\t\t\tr = arrayCacheF32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Float32Array( n );\n\t\t\tarrayCacheF32[ n ] = r;\n\n\t\t}\n\n\t\tif ( nBlocks !== 0 ) {\n\n\t\t\tfirstElem.toArray( r, 0 );\n\n\t\t\tfor ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {\n\n\t\t\t\toffset += blockSize;\n\t\t\t\tarray[ i ].toArray( r, offset );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn r;\n\n\t}\n\n\t// Texture unit allocation\n\n\tfunction allocTexUnits( renderer, n ) {\n\n\t\tvar r = arrayCacheI32[ n ];\n\n\t\tif ( r === undefined ) {\n\n\t\t\tr = new Int32Array( n );\n\t\t\tarrayCacheI32[ n ] = r;\n\n\t\t}\n\n\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\tr[ i ] = renderer.allocTextureUnit();\n\n\t\treturn r;\n\n\t}\n\n\t// --- Setters ---\n\n\t// Note: Defining these methods externally, because they come in a bunch\n\t// and this way their names minify.\n\n\t// Single scalar\n\n\tfunction setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }\n\tfunction setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }\n\n\t// Single float vector (from flat array or THREE.VectorN)\n\n\tfunction setValue2fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform2fv( this.addr, v );\n\t\telse gl.uniform2f( this.addr, v.x, v.y );\n\n\t}\n\n\tfunction setValue3fv( gl, v ) {\n\n\t\tif ( v.x !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.x, v.y, v.z );\n\t\telse if ( v.r !== undefined )\n\t\t\tgl.uniform3f( this.addr, v.r, v.g, v.b );\n\t\telse\n\t\t\tgl.uniform3fv( this.addr, v );\n\n\t}\n\n\tfunction setValue4fv( gl, v ) {\n\n\t\tif ( v.x === undefined ) gl.uniform4fv( this.addr, v );\n\t\telse gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );\n\n\t}\n\n\t// Single matrix (from flat array or MatrixN)\n\n\tfunction setValue2fm( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue3fm( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, v.elements || v );\n\n\t}\n\n\tfunction setValue4fm( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, v.elements || v );\n\n\t}\n\n\t// Single texture (2D / Cube)\n\n\tfunction setValueT1( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTexture2D( v || emptyTexture, unit );\n\n\t}\n\n\tfunction setValueT6( gl, v, renderer ) {\n\n\t\tvar unit = renderer.allocTextureUnit();\n\t\tgl.uniform1i( this.addr, unit );\n\t\trenderer.setTextureCube( v || emptyCubeTexture, unit );\n\n\t}\n\n\t// Integer / Boolean vectors or arrays thereof (always flat arrays)\n\n\tfunction setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }\n\tfunction setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }\n\tfunction setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }\n\n\t// Helper to pick the right setter for the singular case\n\n\tfunction getSingularSetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1f; // FLOAT\n\t\t\tcase 0x8b50: return setValue2fv; // _VEC2\n\t\t\tcase 0x8b51: return setValue3fv; // _VEC3\n\t\t\tcase 0x8b52: return setValue4fv; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValue2fm; // _MAT2\n\t\t\tcase 0x8b5b: return setValue3fm; // _MAT3\n\t\t\tcase 0x8b5c: return setValue4fm; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1i; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// Array of scalars\n\n\tfunction setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }\n\tfunction setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }\n\n\t// Array of vectors (flat or from THREE classes)\n\n\tfunction setValueV2a( gl, v ) {\n\n\t\tgl.uniform2fv( this.addr, flatten( v, this.size, 2 ) );\n\n\t}\n\n\tfunction setValueV3a( gl, v ) {\n\n\t\tgl.uniform3fv( this.addr, flatten( v, this.size, 3 ) );\n\n\t}\n\n\tfunction setValueV4a( gl, v ) {\n\n\t\tgl.uniform4fv( this.addr, flatten( v, this.size, 4 ) );\n\n\t}\n\n\t// Array of matrices (flat or from THREE clases)\n\n\tfunction setValueM2a( gl, v ) {\n\n\t\tgl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) );\n\n\t}\n\n\tfunction setValueM3a( gl, v ) {\n\n\t\tgl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) );\n\n\t}\n\n\tfunction setValueM4a( gl, v ) {\n\n\t\tgl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) );\n\n\t}\n\n\t// Array of textures (2D / Cube)\n\n\tfunction setValueT1a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTexture2D( v[ i ] || emptyTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\tfunction setValueT6a( gl, v, renderer ) {\n\n\t\tvar n = v.length,\n\t\t\tunits = allocTexUnits( renderer, n );\n\n\t\tgl.uniform1iv( this.addr, units );\n\n\t\tfor ( var i = 0; i !== n; ++ i ) {\n\n\t\t\trenderer.setTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );\n\n\t\t}\n\n\t}\n\n\t// Helper to pick the right setter for a pure (bottom-level) array\n\n\tfunction getPureArraySetter( type ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 0x1406: return setValue1fv; // FLOAT\n\t\t\tcase 0x8b50: return setValueV2a; // _VEC2\n\t\t\tcase 0x8b51: return setValueV3a; // _VEC3\n\t\t\tcase 0x8b52: return setValueV4a; // _VEC4\n\n\t\t\tcase 0x8b5a: return setValueM2a; // _MAT2\n\t\t\tcase 0x8b5b: return setValueM3a; // _MAT3\n\t\t\tcase 0x8b5c: return setValueM4a; // _MAT4\n\n\t\t\tcase 0x8b5e: return setValueT1a; // SAMPLER_2D\n\t\t\tcase 0x8b60: return setValueT6a; // SAMPLER_CUBE\n\n\t\t\tcase 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL\n\t\t\tcase 0x8b53: case 0x8b57: return setValue2iv; // _VEC2\n\t\t\tcase 0x8b54: case 0x8b58: return setValue3iv; // _VEC3\n\t\t\tcase 0x8b55: case 0x8b59: return setValue4iv; // _VEC4\n\n\t\t}\n\n\t}\n\n\t// --- Uniform Classes ---\n\n\tfunction SingleUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.setValue = getSingularSetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction PureArrayUniform( id, activeInfo, addr ) {\n\n\t\tthis.id = id;\n\t\tthis.addr = addr;\n\t\tthis.size = activeInfo.size;\n\t\tthis.setValue = getPureArraySetter( activeInfo.type );\n\n\t\t// this.path = activeInfo.name; // DEBUG\n\n\t}\n\n\tfunction StructuredUniform( id ) {\n\n\t\tthis.id = id;\n\n\t\tUniformContainer.call( this ); // mix-in\n\n\t}\n\n\tStructuredUniform.prototype.setValue = function( gl, value ) {\n\n\t\t// Note: Don't need an extra 'renderer' parameter, since samplers\n\t\t// are not allowed in structured uniforms.\n\n\t\tvar seq = this.seq;\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tu.setValue( gl, value[ u.id ] );\n\n\t\t}\n\n\t};\n\n\t// --- Top-level ---\n\n\t// Parser - builds up the property tree from the path strings\n\n\tvar RePathPart = /([\\w\\d_]+)(\\])?(\\[|\\.)?/g;\n\n\t// extracts\n\t// \t- the identifier (member name or array index)\n\t// - followed by an optional right bracket (found when array index)\n\t// - followed by an optional left bracket or dot (type of subscript)\n\t//\n\t// Note: These portions can be read in a non-overlapping fashion and\n\t// allow straightforward parsing of the hierarchy that WebGL encodes\n\t// in the uniform names.\n\n\tfunction addUniform( container, uniformObject ) {\n\n\t\tcontainer.seq.push( uniformObject );\n\t\tcontainer.map[ uniformObject.id ] = uniformObject;\n\n\t}\n\n\tfunction parseUniform( activeInfo, addr, container ) {\n\n\t\tvar path = activeInfo.name,\n\t\t\tpathLength = path.length;\n\n\t\t// reset RegExp object, because of the early exit of a previous run\n\t\tRePathPart.lastIndex = 0;\n\n\t\tfor (; ;) {\n\n\t\t\tvar match = RePathPart.exec( path ),\n\t\t\t\tmatchEnd = RePathPart.lastIndex,\n\n\t\t\t\tid = match[ 1 ],\n\t\t\t\tidIsIndex = match[ 2 ] === ']',\n\t\t\t\tsubscript = match[ 3 ];\n\n\t\t\tif ( idIsIndex ) id = id | 0; // convert to integer\n\n\t\t\tif ( subscript === undefined ||\n\t\t\t\t\tsubscript === '[' && matchEnd + 2 === pathLength ) {\n\t\t\t\t// bare name or \"pure\" bottom-level array \"[0]\" suffix\n\n\t\t\t\taddUniform( container, subscript === undefined ?\n\t\t\t\t\t\tnew SingleUniform( id, activeInfo, addr ) :\n\t\t\t\t\t\tnew PureArrayUniform( id, activeInfo, addr ) );\n\n\t\t\t\tbreak;\n\n\t\t\t} else {\n\t\t\t\t// step into inner node / create it in case it doesn't exist\n\n\t\t\t\tvar map = container.map,\n\t\t\t\t\tnext = map[ id ];\n\n\t\t\t\tif ( next === undefined ) {\n\n\t\t\t\t\tnext = new StructuredUniform( id );\n\t\t\t\t\taddUniform( container, next );\n\n\t\t\t\t}\n\n\t\t\t\tcontainer = next;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t// Root Container\n\n\tfunction WebGLUniforms( gl, program, renderer ) {\n\n\t\tUniformContainer.call( this );\n\n\t\tthis.renderer = renderer;\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS );\n\n\t\tfor ( var i = 0; i < n; ++ i ) {\n\n\t\t\tvar info = gl.getActiveUniform( program, i ),\n\t\t\t\tpath = info.name,\n\t\t\t\taddr = gl.getUniformLocation( program, path );\n\n\t\t\tparseUniform( info, addr, this );\n\n\t\t}\n\n\t}\n\n\tWebGLUniforms.prototype.setValue = function( gl, name, value ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, value, this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.set = function( gl, object, name ) {\n\n\t\tvar u = this.map[ name ];\n\n\t\tif ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer );\n\n\t};\n\n\tWebGLUniforms.prototype.setOptional = function( gl, object, name ) {\n\n\t\tvar v = object[ name ];\n\n\t\tif ( v !== undefined ) this.setValue( gl, name, v );\n\n\t};\n\n\n\t// Static interface\n\n\tWebGLUniforms.upload = function( gl, seq, values, renderer ) {\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ],\n\t\t\t\tv = values[ u.id ];\n\n\t\t\tif ( v.needsUpdate !== false ) {\n\t\t\t\t// note: always updating when .needsUpdate is undefined\n\n\t\t\t\tu.setValue( gl, v.value, renderer );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tWebGLUniforms.seqWithValue = function( seq, values ) {\n\n\t\tvar r = [];\n\n\t\tfor ( var i = 0, n = seq.length; i !== n; ++ i ) {\n\n\t\t\tvar u = seq[ i ];\n\t\t\tif ( u.id in values ) r.push( u );\n\n\t\t}\n\n\t\treturn r;\n\n\t};\n\n\t/**\n\t * Uniform Utilities\n\t */\n\n\tvar UniformsUtils = {\n\n\t\tmerge: function ( uniforms ) {\n\n\t\t\tvar merged = {};\n\n\t\t\tfor ( var u = 0; u < uniforms.length; u ++ ) {\n\n\t\t\t\tvar tmp = this.clone( uniforms[ u ] );\n\n\t\t\t\tfor ( var p in tmp ) {\n\n\t\t\t\t\tmerged[ p ] = tmp[ p ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn merged;\n\n\t\t},\n\n\t\tclone: function ( uniforms_src ) {\n\n\t\t\tvar uniforms_dst = {};\n\n\t\t\tfor ( var u in uniforms_src ) {\n\n\t\t\t\tuniforms_dst[ u ] = {};\n\n\t\t\t\tfor ( var p in uniforms_src[ u ] ) {\n\n\t\t\t\t\tvar parameter_src = uniforms_src[ u ][ p ];\n\n\t\t\t\t\tif ( parameter_src && ( parameter_src.isColor ||\n\t\t\t\t\t\tparameter_src.isMatrix3 || parameter_src.isMatrix4 ||\n\t\t\t\t\t\tparameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||\n\t\t\t\t\t\tparameter_src.isTexture ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.clone();\n\n\t\t\t\t\t} else if ( Array.isArray( parameter_src ) ) {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src.slice();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tuniforms_dst[ u ][ p ] = parameter_src;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn uniforms_dst;\n\n\t\t}\n\n\t};\n\n\tvar alphamap_fragment = \"#ifdef USE_ALPHAMAP\\n\\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\\n#endif\\n\";\n\n\tvar alphamap_pars_fragment = \"#ifdef USE_ALPHAMAP\\n\\tuniform sampler2D alphaMap;\\n#endif\\n\";\n\n\tvar alphatest_fragment = \"#ifdef ALPHATEST\\n\\tif ( diffuseColor.a < ALPHATEST ) discard;\\n#endif\\n\";\n\n\tvar aomap_fragment = \"#ifdef USE_AOMAP\\n\\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\\n\\treflectedLight.indirectDiffuse *= ambientOcclusion;\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\\n\\t#endif\\n#endif\\n\";\n\n\tvar aomap_pars_fragment = \"#ifdef USE_AOMAP\\n\\tuniform sampler2D aoMap;\\n\\tuniform float aoMapIntensity;\\n#endif\";\n\n\tvar begin_vertex = \"\\nvec3 transformed = vec3( position );\\n\";\n\n\tvar beginnormal_vertex = \"\\nvec3 objectNormal = vec3( normal );\\n\";\n\n\tvar bsdfs = \"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\\n\\t\\tif( decayExponent > 0.0 ) {\\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\\n\\t\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\\n\\t\\t\\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\\n\\t\\t\\treturn distanceFalloff * maxDistanceCutoffFactor;\\n#else\\n\\t\\t\\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\\n#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n}\\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\\n\\treturn RECIPROCAL_PI * diffuseColor;\\n}\\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\\n\\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\\n\\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\\n}\\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\treturn 1.0 / ( gl * gv );\\n}\\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\\n\\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\\n\\treturn 0.5 / max( gv + gl, EPSILON );\\n}\\nfloat D_GGX( const in float alpha, const in float dotNH ) {\\n\\tfloat a2 = pow2( alpha );\\n\\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\\n\\treturn RECIPROCAL_PI * a2 / pow2( denom );\\n}\\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat alpha = pow2( roughness );\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\\n\\tfloat D = D_GGX( alpha, dotNH );\\n\\treturn F * ( G * D );\\n}\\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\\n\\tconst float LUT_SIZE = 64.0;\\n\\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\\n\\tconst float LUT_BIAS = 0.5/LUT_SIZE;\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tfloat theta = acos( dot( N, V ) );\\n\\tvec2 uv = vec2(\\n\\t\\tsqrt( saturate( roughness ) ),\\n\\t\\tsaturate( theta / ( 0.5 * PI ) ) );\\n\\tuv = uv * LUT_SCALE + LUT_BIAS;\\n\\treturn uv;\\n}\\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\\n\\tint config = 0;\\n\\tif ( L[0].z > 0.0 ) config += 1;\\n\\tif ( L[1].z > 0.0 ) config += 2;\\n\\tif ( L[2].z > 0.0 ) config += 4;\\n\\tif ( L[3].z > 0.0 ) config += 8;\\n\\tn = 0;\\n\\tif ( config == 0 ) {\\n\\t} else if ( config == 1 ) {\\n\\t\\tn = 3;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 2 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 3 ) {\\n\\t\\tn = 4;\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t\\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t} else if ( config == 4 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t} else if ( config == 5 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 6 ) {\\n\\t\\tn = 4;\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 7 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\\n\\t\\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\\n\\t} else if ( config == 8 ) {\\n\\t\\tn = 3;\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = L[3];\\n\\t} else if ( config == 9 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t\\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t} else if ( config == 10 ) {\\n\\t\\tn = 0;\\n\\t} else if ( config == 11 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\\n\\t\\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\\n\\t} else if ( config == 12 ) {\\n\\t\\tn = 4;\\n\\t\\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t} else if ( config == 13 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = L[3];\\n\\t\\tL[3] = L[2];\\n\\t\\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\\n\\t\\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\\n\\t} else if ( config == 14 ) {\\n\\t\\tn = 5;\\n\\t\\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\\n\\t\\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\\n\\t} else if ( config == 15 ) {\\n\\t\\tn = 4;\\n\\t}\\n\\tif ( n == 3 )\\n\\t\\tL[3] = L[0];\\n\\tif ( n == 4 )\\n\\t\\tL[4] = L[0];\\n}\\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\\n\\tfloat cosTheta = dot( v1, v2 );\\n\\tfloat theta = acos( cosTheta );\\n\\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\\n\\treturn res;\\n}\\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\\n\\trectPoints[0] = pos - halfWidth - halfHeight;\\n\\trectPoints[1] = pos + halfWidth - halfHeight;\\n\\trectPoints[2] = pos + halfWidth + halfHeight;\\n\\trectPoints[3] = pos - halfWidth + halfHeight;\\n}\\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\\n\\tvec3 N = geometry.normal;\\n\\tvec3 V = geometry.viewDir;\\n\\tvec3 P = geometry.position;\\n\\tvec3 T1, T2;\\n\\tT1 = normalize(V - N * dot( V, N ));\\n\\tT2 = - cross( N, T1 );\\n\\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\\n\\tvec3 clippedRect[5];\\n\\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\\n\\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\\n\\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\\n\\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\\n\\tint n;\\n\\tclipQuadToHorizon(clippedRect, n);\\n\\tif ( n == 0 )\\n\\t\\treturn vec3( 0, 0, 0 );\\n\\tclippedRect[0] = normalize( clippedRect[0] );\\n\\tclippedRect[1] = normalize( clippedRect[1] );\\n\\tclippedRect[2] = normalize( clippedRect[2] );\\n\\tclippedRect[3] = normalize( clippedRect[3] );\\n\\tclippedRect[4] = normalize( clippedRect[4] );\\n\\tfloat sum = 0.0;\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\\n\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\\n\\tif (n >= 4)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\\n\\tif (n == 5)\\n\\t\\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\\n\\tsum = max( 0.0, sum );\\n\\tvec3 Lo_i = vec3( sum, sum, sum );\\n\\treturn Lo_i;\\n}\\nvec3 Rect_Area_Light_Specular_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\\n\\t\\tconst in float roughness,\\n\\t\\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tvec2 uv = ltcTextureCoords( geometry, roughness );\\n\\tvec4 brdfLtcApproxParams, t;\\n\\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\\n\\tt = texture2D( ltcMat, uv );\\n\\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\\n\\tmat3 brdfLtcApproxMat = mat3(\\n\\t\\tvec3( 1, 0, t.y ),\\n\\t\\tvec3( 0, t.z, 0 ),\\n\\t\\tvec3( t.w, 0, t.x )\\n\\t);\\n\\tvec3 specularReflectance = integrateLtcBrdfOverRect( geometry, brdfLtcApproxMat, rectPoints );\\n\\tspecularReflectance *= brdfLtcScalar;\\n\\treturn specularReflectance;\\n}\\nvec3 Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\tconst in GeometricContext geometry,\\n\\t\\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\\n\\tvec3 rectPoints[4];\\n\\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\\n\\tmat3 diffuseBrdfMat = mat3(1);\\n\\tvec3 diffuseReflectance = integrateLtcBrdfOverRect( geometry, diffuseBrdfMat, rectPoints );\\n\\treturn diffuseReflectance;\\n}\\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\\n\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\\n\\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\\n\\tvec4 r = roughness * c0 + c1;\\n\\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\\n\\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\\n\\treturn specularColor * AB.x + AB.y;\\n}\\nfloat G_BlinnPhong_Implicit( ) {\\n\\treturn 0.25;\\n}\\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\\n\\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\\n}\\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\\n\\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\\n\\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\\n\\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\\n\\tvec3 F = F_Schlick( specularColor, dotLH );\\n\\tfloat G = G_BlinnPhong_Implicit( );\\n\\tfloat D = D_BlinnPhong( shininess, dotNH );\\n\\treturn F * ( G * D );\\n}\\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\\n\\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\\n}\\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\\n\\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\\n}\\n\";\n\n\tvar bumpmap_pars_fragment = \"#ifdef USE_BUMPMAP\\n\\tuniform sampler2D bumpMap;\\n\\tuniform float bumpScale;\\n\\tvec2 dHdxy_fwd() {\\n\\t\\tvec2 dSTdx = dFdx( vUv );\\n\\t\\tvec2 dSTdy = dFdy( vUv );\\n\\t\\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\\n\\t\\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\\n\\t\\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\\n\\t\\treturn vec2( dBx, dBy );\\n\\t}\\n\\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\\n\\t\\tvec3 vSigmaX = dFdx( surf_pos );\\n\\t\\tvec3 vSigmaY = dFdy( surf_pos );\\n\\t\\tvec3 vN = surf_norm;\\n\\t\\tvec3 R1 = cross( vSigmaY, vN );\\n\\t\\tvec3 R2 = cross( vN, vSigmaX );\\n\\t\\tfloat fDet = dot( vSigmaX, R1 );\\n\\t\\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\\n\\t\\treturn normalize( abs( fDet ) * surf_norm - vGrad );\\n\\t}\\n#endif\\n\";\n\n\tvar clipping_planes_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\\n\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\\n\\t}\\n\\t\\t\\n\\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\\n\\t\\tbool clipped = true;\\n\\t\\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\\n\\t\\t\\tvec4 plane = clippingPlanes[ i ];\\n\\t\\t\\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\\n\\t\\t}\\n\\t\\tif ( clipped ) discard;\\n\\t\\n\\t#endif\\n#endif\\n\";\n\n\tvar clipping_planes_pars_fragment = \"#if NUM_CLIPPING_PLANES > 0\\n\\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\t\\tvarying vec3 vViewPosition;\\n\\t#endif\\n\\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\\n#endif\\n\";\n\n\tvar clipping_planes_pars_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n\";\n\n\tvar clipping_planes_vertex = \"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n\";\n\n\tvar color_fragment = \"#ifdef USE_COLOR\\n\\tdiffuseColor.rgb *= vColor;\\n#endif\";\n\n\tvar color_pars_fragment = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\\n\";\n\n\tvar color_pars_vertex = \"#ifdef USE_COLOR\\n\\tvarying vec3 vColor;\\n#endif\";\n\n\tvar color_vertex = \"#ifdef USE_COLOR\\n\\tvColor.xyz = color.xyz;\\n#endif\";\n\n\tvar common = \"#define PI 3.14159265359\\n#define PI2 6.28318530718\\n#define PI_HALF 1.5707963267949\\n#define RECIPROCAL_PI 0.31830988618\\n#define RECIPROCAL_PI2 0.15915494\\n#define LOG2 1.442695\\n#define EPSILON 1e-6\\n#define saturate(a) clamp( a, 0.0, 1.0 )\\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\\nfloat pow2( const in float x ) { return x*x; }\\nfloat pow3( const in float x ) { return x*x*x; }\\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\\nhighp float rand( const in vec2 uv ) {\\n\\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\\n\\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\\n\\treturn fract(sin(sn) * c);\\n}\\nstruct IncidentLight {\\n\\tvec3 color;\\n\\tvec3 direction;\\n\\tbool visible;\\n};\\nstruct ReflectedLight {\\n\\tvec3 directDiffuse;\\n\\tvec3 directSpecular;\\n\\tvec3 indirectDiffuse;\\n\\tvec3 indirectSpecular;\\n};\\nstruct GeometricContext {\\n\\tvec3 position;\\n\\tvec3 normal;\\n\\tvec3 viewDir;\\n};\\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\\n}\\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\\n\\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\\n}\\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\tfloat distance = dot( planeNormal, point - pointOnPlane );\\n\\treturn - distance * planeNormal + point;\\n}\\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn sign( dot( point - pointOnPlane, planeNormal ) );\\n}\\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\\n\\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\\n}\\nmat3 transpose( const in mat3 v ) {\\n\\tmat3 tmp;\\n\\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\\n\\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\\n\\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\\n\\treturn tmp;\\n}\\n\";\n\n\tvar cube_uv_reflection_fragment = \"#ifdef ENVMAP_TYPE_CUBE_UV\\n#define cubeUV_textureSize (1024.0)\\nint getFaceFromDirection(vec3 direction) {\\n\\tvec3 absDirection = abs(direction);\\n\\tint face = -1;\\n\\tif( absDirection.x > absDirection.z ) {\\n\\t\\tif(absDirection.x > absDirection.y )\\n\\t\\t\\tface = direction.x > 0.0 ? 0 : 3;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\telse {\\n\\t\\tif(absDirection.z > absDirection.y )\\n\\t\\t\\tface = direction.z > 0.0 ? 2 : 5;\\n\\t\\telse\\n\\t\\t\\tface = direction.y > 0.0 ? 1 : 4;\\n\\t}\\n\\treturn face;\\n}\\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\\n\\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\\n\\tfloat dxRoughness = dFdx(roughness);\\n\\tfloat dyRoughness = dFdy(roughness);\\n\\tvec3 dx = dFdx( vec * scale * dxRoughness );\\n\\tvec3 dy = dFdy( vec * scale * dyRoughness );\\n\\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\\n\\td = clamp(d, 1.0, cubeUV_rangeClamp);\\n\\tfloat mipLevel = 0.5 * log2(d);\\n\\treturn vec2(floor(mipLevel), fract(mipLevel));\\n}\\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\\n\\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\\n\\tfloat a = 16.0 * cubeUV_rcpTextureSize;\\n\\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\\n\\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\\n\\tfloat powScale = exp2_packed.x * exp2_packed.y;\\n\\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\\n\\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\\n\\tbool bRes = mipLevel == 0.0;\\n\\tscale = bRes && (scale < a) ? a : scale;\\n\\tvec3 r;\\n\\tvec2 offset;\\n\\tint face = getFaceFromDirection(direction);\\n\\tfloat rcpPowScale = 1.0 / powScale;\\n\\tif( face == 0) {\\n\\t\\tr = vec3(direction.x, -direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 1) {\\n\\t\\tr = vec3(direction.y, direction.x, direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 2) {\\n\\t\\tr = vec3(direction.z, direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\\n\\t}\\n\\telse if( face == 3) {\\n\\t\\tr = vec3(direction.x, direction.z, direction.y);\\n\\t\\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse if( face == 4) {\\n\\t\\tr = vec3(direction.y, direction.x, -direction.z);\\n\\t\\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\telse {\\n\\t\\tr = vec3(direction.z, -direction.x, direction.y);\\n\\t\\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\\n\\t\\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\\n\\t}\\n\\tr = normalize(r);\\n\\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\\n\\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\\n\\tvec2 base = offset + vec2( texelOffset );\\n\\treturn base + s * ( scale - 2.0 * texelOffset );\\n}\\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\\n\\tfloat roughnessVal = roughness* cubeUV_maxLods3;\\n\\tfloat r1 = floor(roughnessVal);\\n\\tfloat r2 = r1 + 1.0;\\n\\tfloat t = fract(roughnessVal);\\n\\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\\n\\tfloat s = mipInfo.y;\\n\\tfloat level0 = mipInfo.x;\\n\\tfloat level1 = level0 + 1.0;\\n\\tlevel1 = level1 > 5.0 ? 5.0 : level1;\\n\\tlevel0 += min( floor( s + 0.5 ), 5.0 );\\n\\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\\n\\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\\n\\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\\n\\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\\n\\tvec4 result = mix(color10, color20, t);\\n\\treturn vec4(result.rgb, 1.0);\\n}\\n#endif\\n\";\n\n\tvar defaultnormal_vertex = \"#ifdef FLIP_SIDED\\n\\tobjectNormal = -objectNormal;\\n#endif\\nvec3 transformedNormal = normalMatrix * objectNormal;\\n\";\n\n\tvar displacementmap_pars_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\tuniform sampler2D displacementMap;\\n\\tuniform float displacementScale;\\n\\tuniform float displacementBias;\\n#endif\\n\";\n\n\tvar displacementmap_vertex = \"#ifdef USE_DISPLACEMENTMAP\\n\\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\\n#endif\\n\";\n\n\tvar emissivemap_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\\n\\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\\n\\ttotalEmissiveRadiance *= emissiveColor.rgb;\\n#endif\\n\";\n\n\tvar emissivemap_pars_fragment = \"#ifdef USE_EMISSIVEMAP\\n\\tuniform sampler2D emissiveMap;\\n#endif\\n\";\n\n\tvar encodings_fragment = \" gl_FragColor = linearToOutputTexel( gl_FragColor );\\n\";\n\n\tvar encodings_pars_fragment = \"\\nvec4 LinearToLinear( in vec4 value ) {\\n\\treturn value;\\n}\\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\\n}\\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\\n\\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\\n}\\nvec4 sRGBToLinear( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\\n}\\nvec4 LinearTosRGB( in vec4 value ) {\\n\\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\\n}\\nvec4 RGBEToLinear( in vec4 value ) {\\n\\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\\n}\\nvec4 LinearToRGBE( in vec4 value ) {\\n\\tfloat maxComponent = max( max( value.r, value.g ), value.b );\\n\\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\\n\\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\\n}\\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\\n}\\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\\n\\tM = ceil( M * 255.0 ) / 255.0;\\n\\treturn vec4( value.rgb / ( M * maxRange ), M );\\n}\\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\\n\\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\\n}\\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\\n\\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\\n\\tfloat D = max( maxRange / maxRGB, 1.0 );\\n\\tD = min( floor( D ) / 255.0, 1.0 );\\n\\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\\n}\\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\\nvec4 LinearToLogLuv( in vec4 value ) {\\n\\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\\n\\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\\n\\tvec4 vResult;\\n\\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\\n\\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\\n\\tvResult.w = fract(Le);\\n\\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\\n\\treturn vResult;\\n}\\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\\nvec4 LogLuvToLinear( in vec4 value ) {\\n\\tfloat Le = value.z * 255.0 + value.w;\\n\\tvec3 Xp_Y_XYZp;\\n\\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\\n\\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\\n\\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\\n\\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\\n\\treturn vec4( max(vRGB, 0.0), 1.0 );\\n}\\n\";\n\n\tvar envmap_fragment = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#else\\n\\t\\tvec3 reflectVec = vReflect;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\\n\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\tvec2 sampleUV;\\n\\t\\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\\n\\t\\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\tvec4 envColor = texture2D( envMap, sampleUV );\\n\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\\n\\t\\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\\n\\t#else\\n\\t\\tvec4 envColor = vec4( 0.0 );\\n\\t#endif\\n\\tenvColor = envMapTexelToLinear( envColor );\\n\\t#ifdef ENVMAP_BLENDING_MULTIPLY\\n\\t\\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_MIX )\\n\\t\\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\\n\\t#elif defined( ENVMAP_BLENDING_ADD )\\n\\t\\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_fragment = \"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\\n\\tuniform float reflectivity;\\n\\tuniform float envMapIntensity;\\n#endif\\n#ifdef USE_ENVMAP\\n\\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#endif\\n\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\tuniform samplerCube envMap;\\n\\t#else\\n\\t\\tuniform sampler2D envMap;\\n\\t#endif\\n\\tuniform float flipEnvMap;\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\\n\\t\\tuniform float refractionRatio;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_pars_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvarying vec3 vWorldPosition;\\n\\t#else\\n\\t\\tvarying vec3 vReflect;\\n\\t\\tuniform float refractionRatio;\\n\\t#endif\\n#endif\\n\";\n\n\tvar envmap_vertex = \"#ifdef USE_ENVMAP\\n\\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\\n\\t\\tvWorldPosition = worldPosition.xyz;\\n\\t#else\\n\\t\\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\\n\\t\\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvReflect = reflect( cameraToVertex, worldNormal );\\n\\t\\t#else\\n\\t\\t\\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\\n\\t\\t#endif\\n\\t#endif\\n#endif\\n\";\n\n\tvar fog_vertex = \"\\n#ifdef USE_FOG\\nfogDepth = -mvPosition.z;\\n#endif\";\n\n\tvar fog_pars_vertex = \"#ifdef USE_FOG\\n varying float fogDepth;\\n#endif\\n\";\n\n\tvar fog_fragment = \"#ifdef USE_FOG\\n\\t#ifdef FOG_EXP2\\n\\t\\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\\n\\t#else\\n\\t\\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\\n\\t#endif\\n\\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\\n#endif\\n\";\n\n\tvar fog_pars_fragment = \"#ifdef USE_FOG\\n\\tuniform vec3 fogColor;\\n\\tvarying float fogDepth;\\n\\t#ifdef FOG_EXP2\\n\\t\\tuniform float fogDensity;\\n\\t#else\\n\\t\\tuniform float fogNear;\\n\\t\\tuniform float fogFar;\\n\\t#endif\\n#endif\\n\";\n\n\tvar gradientmap_pars_fragment = \"#ifdef TOON\\n\\tuniform sampler2D gradientMap;\\n\\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\\n\\t\\tfloat dotNL = dot( normal, lightDirection );\\n\\t\\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\\n\\t\\t#ifdef USE_GRADIENTMAP\\n\\t\\t\\treturn texture2D( gradientMap, coord ).rgb;\\n\\t\\t#else\\n\\t\\t\\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lightmap_fragment = \"#ifdef USE_LIGHTMAP\\n\\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n#endif\\n\";\n\n\tvar lightmap_pars_fragment = \"#ifdef USE_LIGHTMAP\\n\\tuniform sampler2D lightMap;\\n\\tuniform float lightMapIntensity;\\n#endif\";\n\n\tvar lights_lambert_vertex = \"vec3 diffuse = vec3( 1.0 );\\nGeometricContext geometry;\\ngeometry.position = mvPosition.xyz;\\ngeometry.normal = normalize( transformedNormal );\\ngeometry.viewDir = normalize( -mvPosition.xyz );\\nGeometricContext backGeometry;\\nbackGeometry.position = geometry.position;\\nbackGeometry.normal = -geometry.normal;\\nbackGeometry.viewDir = geometry.viewDir;\\nvLightFront = vec3( 0.0 );\\n#ifdef DOUBLE_SIDED\\n\\tvLightBack = vec3( 0.0 );\\n#endif\\nIncidentLight directLight;\\nfloat dotNL;\\nvec3 directLightColor_Diffuse;\\n#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\\n\\t\\tdotNL = dot( geometry.normal, directLight.direction );\\n\\t\\tdirectLightColor_Diffuse = PI * directLight.color;\\n\\t\\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\\n\\t\\t#endif\\n\\t}\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t#ifdef DOUBLE_SIDED\\n\\t\\t\\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar lights_pars = \"uniform vec3 ambientLightColor;\\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\\n\\tvec3 irradiance = ambientLightColor;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treturn irradiance;\\n}\\n#if NUM_DIR_LIGHTS > 0\\n\\tstruct DirectionalLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\\n\\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tdirectLight.color = directionalLight.color;\\n\\t\\tdirectLight.direction = directionalLight.direction;\\n\\t\\tdirectLight.visible = true;\\n\\t}\\n#endif\\n#if NUM_POINT_LIGHTS > 0\\n\\tstruct PointLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\\n\\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = pointLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tdirectLight.color = pointLight.color;\\n\\t\\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\\n\\t\\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\\n\\t}\\n#endif\\n#if NUM_SPOT_LIGHTS > 0\\n\\tstruct SpotLight {\\n\\t\\tvec3 position;\\n\\t\\tvec3 direction;\\n\\t\\tvec3 color;\\n\\t\\tfloat distance;\\n\\t\\tfloat decay;\\n\\t\\tfloat coneCos;\\n\\t\\tfloat penumbraCos;\\n\\t\\tint shadow;\\n\\t\\tfloat shadowBias;\\n\\t\\tfloat shadowRadius;\\n\\t\\tvec2 shadowMapSize;\\n\\t};\\n\\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\\n\\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\\n\\t\\tvec3 lVector = spotLight.position - geometry.position;\\n\\t\\tdirectLight.direction = normalize( lVector );\\n\\t\\tfloat lightDistance = length( lVector );\\n\\t\\tfloat angleCos = dot( directLight.direction, spotLight.direction );\\n\\t\\tif ( angleCos > spotLight.coneCos ) {\\n\\t\\t\\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\\n\\t\\t\\tdirectLight.color = spotLight.color;\\n\\t\\t\\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\\n\\t\\t\\tdirectLight.visible = true;\\n\\t\\t} else {\\n\\t\\t\\tdirectLight.color = vec3( 0.0 );\\n\\t\\t\\tdirectLight.visible = false;\\n\\t\\t}\\n\\t}\\n#endif\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tstruct RectAreaLight {\\n\\t\\tvec3 color;\\n\\t\\tvec3 position;\\n\\t\\tvec3 halfWidth;\\n\\t\\tvec3 halfHeight;\\n\\t};\\n\\tuniform sampler2D ltcMat;\\tuniform sampler2D ltcMag;\\n\\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\\n#endif\\n#if NUM_HEMI_LIGHTS > 0\\n\\tstruct HemisphereLight {\\n\\t\\tvec3 direction;\\n\\t\\tvec3 skyColor;\\n\\t\\tvec3 groundColor;\\n\\t};\\n\\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\\n\\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\\n\\t\\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\\n\\t\\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\\n\\t\\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tirradiance *= PI;\\n\\t\\t#endif\\n\\t\\treturn irradiance;\\n\\t}\\n#endif\\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\\n\\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\\n\\t\\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\\n\\t\\t#else\\n\\t\\t\\tvec4 envMapColor = vec4( 0.0 );\\n\\t\\t#endif\\n\\t\\treturn PI * envMapColor.rgb * envMapIntensity;\\n\\t}\\n\\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\tfloat maxMIPLevelScalar = float( maxMIPLevel );\\n\\t\\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\\n\\t\\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\\n\\t}\\n\\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\\n\\t\\t#ifdef ENVMAP_MODE_REFLECTION\\n\\t\\t\\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\\n\\t\\t#else\\n\\t\\t\\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\\n\\t\\t#endif\\n\\t\\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\\n\\t\\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\\n\\t\\t#ifdef ENVMAP_TYPE_CUBE\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\t\\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\\n\\t\\t\\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\\n\\t\\t#elif defined( ENVMAP_TYPE_EQUIREC )\\n\\t\\t\\tvec2 sampleUV;\\n\\t\\t\\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\\n\\t\\t\\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#elif defined( ENVMAP_TYPE_SPHERE )\\n\\t\\t\\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\\n\\t\\t\\t#ifdef TEXTURE_LOD_EXT\\n\\t\\t\\t\\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#else\\n\\t\\t\\t\\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\\n\\t\\t\\t#endif\\n\\t\\t\\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\\n\\t\\t#endif\\n\\t\\treturn envMapColor.rgb * envMapIntensity;\\n\\t}\\n#endif\\n\";\n\n\tvar lights_phong_fragment = \"BlinnPhongMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb;\\nmaterial.specularColor = specular;\\nmaterial.specularShininess = shininess;\\nmaterial.specularStrength = specularStrength;\\n\";\n\n\tvar lights_phong_pars_fragment = \"varying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\nstruct BlinnPhongMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tvec3\\tspecularColor;\\n\\tfloat\\tspecularShininess;\\n\\tfloat\\tspecularStrength;\\n};\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff / PI2;\\n\\t}\\n#endif\\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifdef TOON\\n\\t\\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\\n\\t#else\\n\\t\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\t\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#endif\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\\n}\\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_BlinnPhong\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_BlinnPhong\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_BlinnPhong\\n#define Material_LightProbeLOD( material )\\t(0)\\n\";\n\n\tvar lights_physical_fragment = \"PhysicalMaterial material;\\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\\n#ifdef STANDARD\\n\\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\\n#else\\n\\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\\n\\tmaterial.clearCoat = saturate( clearCoat );\\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\\n#endif\\n\";\n\n\tvar lights_physical_pars_fragment = \"struct PhysicalMaterial {\\n\\tvec3\\tdiffuseColor;\\n\\tfloat\\tspecularRoughness;\\n\\tvec3\\tspecularColor;\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoat;\\n\\t\\tfloat clearCoatRoughness;\\n\\t#endif\\n};\\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\\n\\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\\n}\\n#if NUM_RECT_AREA_LIGHTS > 0\\n\\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t\\tvec3 matDiffColor = material.diffuseColor;\\n\\t\\tvec3 matSpecColor = material.specularColor;\\n\\t\\tvec3 lightColor = rectAreaLight.color;\\n\\t\\tfloat roughness = material.specularRoughness;\\n\\t\\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\\n\\t\\t\\t\\troughness,\\n\\t\\t\\t\\tltcMat, ltcMag );\\n\\t\\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\\n\\t\\t\\t\\tgeometry,\\n\\t\\t\\t\\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\\n\\t\\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\\n\\t\\treflectedLight.directDiffuse += lightColor * matDiffColor * diff;\\n\\t}\\n#endif\\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\\n\\tvec3 irradiance = dotNL * directLight.color;\\n\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\tirradiance *= PI;\\n\\t#endif\\n\\t#ifndef STANDARD\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\\n\\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\\n}\\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\\n\\t#ifndef STANDARD\\n\\t\\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\\n\\t\\tfloat dotNL = dotNV;\\n\\t\\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\\n\\t#else\\n\\t\\tfloat clearCoatDHR = 0.0;\\n\\t#endif\\n\\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\\n\\t#ifndef STANDARD\\n\\t\\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\\n\\t#endif\\n}\\n#define RE_Direct\\t\\t\\t\\tRE_Direct_Physical\\n#define RE_Direct_RectArea\\t\\tRE_Direct_RectArea_Physical\\n#define RE_IndirectDiffuse\\t\\tRE_IndirectDiffuse_Physical\\n#define RE_IndirectSpecular\\t\\tRE_IndirectSpecular_Physical\\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\\n\\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\\n}\\n\";\n\n\tvar lights_template = \"\\nGeometricContext geometry;\\ngeometry.position = - vViewPosition;\\ngeometry.normal = normal;\\ngeometry.viewDir = normalize( vViewPosition );\\nIncidentLight directLight;\\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\\n\\t\\t#ifdef USE_SHADOWMAP\\n\\t\\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t\\t#endif\\n\\t\\tRE_Direct( directLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\\n\\tRectAreaLight rectAreaLight;\\n\\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\\n\\t\\trectAreaLight = rectAreaLights[ i ];\\n\\t\\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\\n\\t}\\n#endif\\n#if defined( RE_IndirectDiffuse )\\n\\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t\\t#ifndef PHYSICALLY_CORRECT_LIGHTS\\n\\t\\t\\tlightMapIrradiance *= PI;\\n\\t\\t#endif\\n\\t\\tirradiance += lightMapIrradiance;\\n\\t#endif\\n\\t#if ( NUM_HEMI_LIGHTS > 0 )\\n\\t\\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\\n\\t\\t\\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\\n\\t\\t}\\n\\t#endif\\n\\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\\n\\t\\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\\n\\t#endif\\n\\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\\n#endif\\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\\n\\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\\n\\t#ifndef STANDARD\\n\\t\\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\\n\\t#else\\n\\t\\tvec3 clearCoatRadiance = vec3( 0.0 );\\n\\t#endif\\n\\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\\n#endif\\n\";\n\n\tvar logdepthbuf_fragment = \"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\\n\\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\\n#endif\";\n\n\tvar logdepthbuf_pars_fragment = \"#ifdef USE_LOGDEPTHBUF\\n\\tuniform float logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n#endif\\n\";\n\n\tvar logdepthbuf_pars_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvarying float vFragDepth;\\n\\t#endif\\n\\tuniform float logDepthBufFC;\\n#endif\";\n\n\tvar logdepthbuf_vertex = \"#ifdef USE_LOGDEPTHBUF\\n\\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\\n\\t#ifdef USE_LOGDEPTHBUF_EXT\\n\\t\\tvFragDepth = 1.0 + gl_Position.w;\\n\\t#else\\n\\t\\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\\n\\t#endif\\n#endif\\n\";\n\n\tvar map_fragment = \"#ifdef USE_MAP\\n\\tvec4 texelColor = texture2D( map, vUv );\\n\\ttexelColor = mapTexelToLinear( texelColor );\\n\\tdiffuseColor *= texelColor;\\n#endif\\n\";\n\n\tvar map_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar map_particle_fragment = \"#ifdef USE_MAP\\n\\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\\n\\tdiffuseColor *= mapTexelToLinear( mapTexel );\\n#endif\\n\";\n\n\tvar map_particle_pars_fragment = \"#ifdef USE_MAP\\n\\tuniform vec4 offsetRepeat;\\n\\tuniform sampler2D map;\\n#endif\\n\";\n\n\tvar metalnessmap_fragment = \"float metalnessFactor = metalness;\\n#ifdef USE_METALNESSMAP\\n\\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\\n\\tmetalnessFactor *= texelMetalness.r;\\n#endif\\n\";\n\n\tvar metalnessmap_pars_fragment = \"#ifdef USE_METALNESSMAP\\n\\tuniform sampler2D metalnessMap;\\n#endif\";\n\n\tvar morphnormal_vertex = \"#ifdef USE_MORPHNORMALS\\n\\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\\n\\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\\n\\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\\n\\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\\n#endif\\n\";\n\n\tvar morphtarget_pars_vertex = \"#ifdef USE_MORPHTARGETS\\n\\t#ifndef USE_MORPHNORMALS\\n\\tuniform float morphTargetInfluences[ 8 ];\\n\\t#else\\n\\tuniform float morphTargetInfluences[ 4 ];\\n\\t#endif\\n#endif\";\n\n\tvar morphtarget_vertex = \"#ifdef USE_MORPHTARGETS\\n\\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\\n\\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\\n\\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\\n\\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\\n\\t#ifndef USE_MORPHNORMALS\\n\\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\\n\\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\\n\\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\\n\\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar normal_flip = \"#ifdef DOUBLE_SIDED\\n\\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\\n#else\\n\\tfloat flipNormal = 1.0;\\n#endif\\n\";\n\n\tvar normal_fragment = \"#ifdef FLAT_SHADED\\n\\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\\n\\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\\n\\tvec3 normal = normalize( cross( fdx, fdy ) );\\n#else\\n\\tvec3 normal = normalize( vNormal ) * flipNormal;\\n#endif\\n#ifdef USE_NORMALMAP\\n\\tnormal = perturbNormal2Arb( -vViewPosition, normal );\\n#elif defined( USE_BUMPMAP )\\n\\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\\n#endif\\n\";\n\n\tvar normalmap_pars_fragment = \"#ifdef USE_NORMALMAP\\n\\tuniform sampler2D normalMap;\\n\\tuniform vec2 normalScale;\\n\\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\\n\\t\\tvec3 q0 = dFdx( eye_pos.xyz );\\n\\t\\tvec3 q1 = dFdy( eye_pos.xyz );\\n\\t\\tvec2 st0 = dFdx( vUv.st );\\n\\t\\tvec2 st1 = dFdy( vUv.st );\\n\\t\\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\\n\\t\\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\\n\\t\\tvec3 N = normalize( surf_norm );\\n\\t\\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\\n\\t\\tmapN.xy = normalScale * mapN.xy;\\n\\t\\tmat3 tsn = mat3( S, T, N );\\n\\t\\treturn normalize( tsn * mapN );\\n\\t}\\n#endif\\n\";\n\n\tvar packing = \"vec3 packNormalToRGB( const in vec3 normal ) {\\n\\treturn normalize( normal ) * 0.5 + 0.5;\\n}\\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\\n\\treturn 1.0 - 2.0 * rgb.xyz;\\n}\\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\\nconst float ShiftRight8 = 1. / 256.;\\nvec4 packDepthToRGBA( const in float v ) {\\n\\tvec4 r = vec4( fract( v * PackFactors ), v );\\n\\tr.yzw -= r.xyz * ShiftRight8;\\treturn r * PackUpscale;\\n}\\nfloat unpackRGBAToDepth( const in vec4 v ) {\\n\\treturn dot( v, UnpackFactors );\\n}\\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn ( viewZ + near ) / ( near - far );\\n}\\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\\n\\treturn linearClipZ * ( near - far ) - near;\\n}\\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\\n\\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\\n}\\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\\n\\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\\n}\\n\";\n\n\tvar premultiplied_alpha_fragment = \"#ifdef PREMULTIPLIED_ALPHA\\n\\tgl_FragColor.rgb *= gl_FragColor.a;\\n#endif\\n\";\n\n\tvar project_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 mvPosition = modelViewMatrix * skinned;\\n#else\\n\\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\\n#endif\\ngl_Position = projectionMatrix * mvPosition;\\n\";\n\n\tvar roughnessmap_fragment = \"float roughnessFactor = roughness;\\n#ifdef USE_ROUGHNESSMAP\\n\\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\\n\\troughnessFactor *= texelRoughness.r;\\n#endif\\n\";\n\n\tvar roughnessmap_pars_fragment = \"#ifdef USE_ROUGHNESSMAP\\n\\tuniform sampler2D roughnessMap;\\n#endif\";\n\n\tvar shadowmap_pars_fragment = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n\\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\\n\\t\\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\\n\\t}\\n\\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\\n\\t\\tconst vec2 offset = vec2( 0.0, 1.0 );\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / size;\\n\\t\\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\\n\\t\\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\\n\\t\\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\\n\\t\\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\\n\\t\\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\\n\\t\\tvec2 f = fract( uv * size + 0.5 );\\n\\t\\tfloat a = mix( lb, lt, f.y );\\n\\t\\tfloat b = mix( rb, rt, f.y );\\n\\t\\tfloat c = mix( a, b, f.x );\\n\\t\\treturn c;\\n\\t}\\n\\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tshadowCoord.xyz /= shadowCoord.w;\\n\\t\\tshadowCoord.z += shadowBias;\\n\\t\\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\\n\\t\\tbool inFrustum = all( inFrustumVec );\\n\\t\\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\\n\\t\\tbool frustumTest = all( frustumTestVec );\\n\\t\\tif ( frustumTest ) {\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\\n\\t\\t\\tfloat dx0 = - texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy0 = - texelSize.y * shadowRadius;\\n\\t\\t\\tfloat dx1 = + texelSize.x * shadowRadius;\\n\\t\\t\\tfloat dy1 = + texelSize.y * shadowRadius;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\\n\\t\\t\\t\\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\\n\\t\\t#endif\\n\\t\\t}\\n\\t\\treturn 1.0;\\n\\t}\\n\\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\\n\\t\\tvec3 absV = abs( v );\\n\\t\\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\\n\\t\\tabsV *= scaleToCube;\\n\\t\\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\\n\\t\\tvec2 planar = v.xy;\\n\\t\\tfloat almostATexel = 1.5 * texelSizeY;\\n\\t\\tfloat almostOne = 1.0 - almostATexel;\\n\\t\\tif ( absV.z >= almostOne ) {\\n\\t\\t\\tif ( v.z > 0.0 )\\n\\t\\t\\t\\tplanar.x = 4.0 - v.x;\\n\\t\\t} else if ( absV.x >= almostOne ) {\\n\\t\\t\\tfloat signX = sign( v.x );\\n\\t\\t\\tplanar.x = v.z * signX + 2.0 * signX;\\n\\t\\t} else if ( absV.y >= almostOne ) {\\n\\t\\t\\tfloat signY = sign( v.y );\\n\\t\\t\\tplanar.x = v.x + 2.0 * signY + 2.0;\\n\\t\\t\\tplanar.y = v.z * signY - 2.0;\\n\\t\\t}\\n\\t\\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\\n\\t}\\n\\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\\n\\t\\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\\n\\t\\tvec3 lightToPosition = shadowCoord.xyz;\\n\\t\\tvec3 bd3D = normalize( lightToPosition );\\n\\t\\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\\n\\t\\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\\n\\t\\t\\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\\n\\t\\t\\treturn (\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\\n\\t\\t\\t\\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\\n\\t\\t\\t) * ( 1.0 / 9.0 );\\n\\t\\t#else\\n\\t\\t\\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\\n\\t\\t#endif\\n\\t}\\n#endif\\n\";\n\n\tvar shadowmap_pars_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\t\\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\\n\\t\\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\t\\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\\n\\t\\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\t\\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\\n\\t\\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmap_vertex = \"#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\\n\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar shadowmask_pars_fragment = \"float getShadowMask() {\\n\\tfloat shadow = 1.0;\\n\\t#ifdef USE_SHADOWMAP\\n\\t#if NUM_DIR_LIGHTS > 0\\n\\tDirectionalLight directionalLight;\\n\\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\\n\\t\\tdirectionalLight = directionalLights[ i ];\\n\\t\\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_SPOT_LIGHTS > 0\\n\\tSpotLight spotLight;\\n\\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\\n\\t\\tspotLight = spotLights[ i ];\\n\\t\\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#if NUM_POINT_LIGHTS > 0\\n\\tPointLight pointLight;\\n\\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\\n\\t\\tpointLight = pointLights[ i ];\\n\\t\\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\\n\\t}\\n\\t#endif\\n\\t#endif\\n\\treturn shadow;\\n}\\n\";\n\n\tvar skinbase_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\\n\\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\\n\\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\\n\\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\\n#endif\";\n\n\tvar skinning_pars_vertex = \"#ifdef USE_SKINNING\\n\\tuniform mat4 bindMatrix;\\n\\tuniform mat4 bindMatrixInverse;\\n\\t#ifdef BONE_TEXTURE\\n\\t\\tuniform sampler2D boneTexture;\\n\\t\\tuniform int boneTextureWidth;\\n\\t\\tuniform int boneTextureHeight;\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tfloat j = i * 4.0;\\n\\t\\t\\tfloat x = mod( j, float( boneTextureWidth ) );\\n\\t\\t\\tfloat y = floor( j / float( boneTextureWidth ) );\\n\\t\\t\\tfloat dx = 1.0 / float( boneTextureWidth );\\n\\t\\t\\tfloat dy = 1.0 / float( boneTextureHeight );\\n\\t\\t\\ty = dy * ( y + 0.5 );\\n\\t\\t\\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\\n\\t\\t\\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\\n\\t\\t\\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\\n\\t\\t\\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\\n\\t\\t\\tmat4 bone = mat4( v1, v2, v3, v4 );\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#else\\n\\t\\tuniform mat4 boneMatrices[ MAX_BONES ];\\n\\t\\tmat4 getBoneMatrix( const in float i ) {\\n\\t\\t\\tmat4 bone = boneMatrices[ int(i) ];\\n\\t\\t\\treturn bone;\\n\\t\\t}\\n\\t#endif\\n#endif\\n\";\n\n\tvar skinning_vertex = \"#ifdef USE_SKINNING\\n\\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\\n\\tvec4 skinned = vec4( 0.0 );\\n\\tskinned += boneMatX * skinVertex * skinWeight.x;\\n\\tskinned += boneMatY * skinVertex * skinWeight.y;\\n\\tskinned += boneMatZ * skinVertex * skinWeight.z;\\n\\tskinned += boneMatW * skinVertex * skinWeight.w;\\n\\tskinned = bindMatrixInverse * skinned;\\n#endif\\n\";\n\n\tvar skinnormal_vertex = \"#ifdef USE_SKINNING\\n\\tmat4 skinMatrix = mat4( 0.0 );\\n\\tskinMatrix += skinWeight.x * boneMatX;\\n\\tskinMatrix += skinWeight.y * boneMatY;\\n\\tskinMatrix += skinWeight.z * boneMatZ;\\n\\tskinMatrix += skinWeight.w * boneMatW;\\n\\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\\n\\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\\n#endif\\n\";\n\n\tvar specularmap_fragment = \"float specularStrength;\\n#ifdef USE_SPECULARMAP\\n\\tvec4 texelSpecular = texture2D( specularMap, vUv );\\n\\tspecularStrength = texelSpecular.r;\\n#else\\n\\tspecularStrength = 1.0;\\n#endif\";\n\n\tvar specularmap_pars_fragment = \"#ifdef USE_SPECULARMAP\\n\\tuniform sampler2D specularMap;\\n#endif\";\n\n\tvar tonemapping_fragment = \"#if defined( TONE_MAPPING )\\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\\n#endif\\n\";\n\n\tvar tonemapping_pars_fragment = \"#define saturate(a) clamp( a, 0.0, 1.0 )\\nuniform float toneMappingExposure;\\nuniform float toneMappingWhitePoint;\\nvec3 LinearToneMapping( vec3 color ) {\\n\\treturn toneMappingExposure * color;\\n}\\nvec3 ReinhardToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( color / ( vec3( 1.0 ) + color ) );\\n}\\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\\nvec3 Uncharted2ToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\\n}\\nvec3 OptimizedCineonToneMapping( vec3 color ) {\\n\\tcolor *= toneMappingExposure;\\n\\tcolor = max( vec3( 0.0 ), color - 0.004 );\\n\\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\\n}\\n\";\n\n\tvar uv_pars_fragment = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n#endif\";\n\n\tvar uv_pars_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvarying vec2 vUv;\\n\\tuniform vec4 offsetRepeat;\\n#endif\\n\";\n\n\tvar uv_vertex = \"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\\n\\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\\n#endif\";\n\n\tvar uv2_pars_fragment = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_pars_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tattribute vec2 uv2;\\n\\tvarying vec2 vUv2;\\n#endif\";\n\n\tvar uv2_vertex = \"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\\n\\tvUv2 = uv2;\\n#endif\";\n\n\tvar worldpos_vertex = \"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\\n\\t#ifdef USE_SKINNING\\n\\t\\tvec4 worldPosition = modelMatrix * skinned;\\n\\t#else\\n\\t\\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\n\\t#endif\\n#endif\\n\";\n\n\tvar cube_frag = \"uniform samplerCube tCube;\\nuniform float tFlip;\\nuniform float opacity;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\\n\\tgl_FragColor.a *= opacity;\\n}\\n\";\n\n\tvar cube_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar depth_frag = \"#if DEPTH_PACKING == 3200\\n\\tuniform float opacity;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( 1.0 );\\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tdiffuseColor.a = opacity;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#if DEPTH_PACKING == 3200\\n\\t\\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\\n\\t#elif DEPTH_PACKING == 3201\\n\\t\\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\\n\\t#endif\\n}\\n\";\n\n\tvar depth_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar distanceRGBA_frag = \"uniform vec3 lightPos;\\nvarying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\nvoid main () {\\n\\t#include \\n\\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\\n}\\n\";\n\n\tvar distanceRGBA_vert = \"varying vec4 vWorldPosition;\\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvWorldPosition = worldPosition;\\n}\\n\";\n\n\tvar equirect_frag = \"uniform sampler2D tEquirect;\\nuniform float tFlip;\\nvarying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvec3 direction = normalize( vWorldPosition );\\n\\tvec2 sampleUV;\\n\\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\\n\\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\\n\\tgl_FragColor = texture2D( tEquirect, sampleUV );\\n}\\n\";\n\n\tvar equirect_vert = \"varying vec3 vWorldPosition;\\n#include \\nvoid main() {\\n\\tvWorldPosition = transformDirection( position, modelMatrix );\\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\nuniform float dashSize;\\nuniform float totalSize;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\\n\\t\\tdiscard;\\n\\t}\\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar linedashed_vert = \"uniform float scale;\\nattribute float lineDistance;\\nvarying float vLineDistance;\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvLineDistance = scale * lineDistance;\\n\\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\\n\\tgl_Position = projectionMatrix * mvPosition;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\t#ifdef USE_LIGHTMAP\\n\\t\\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\\n\\t#else\\n\\t\\treflectedLight.indirectDiffuse += vec3( 1.0 );\\n\\t#endif\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\\n\\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshbasic_vert = \"#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_ENVMAP\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_frag = \"uniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float opacity;\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\\n\\t#include \\n\\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\\n\\t#ifdef DOUBLE_SIDED\\n\\t\\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\\n\\t#else\\n\\t\\treflectedLight.directDiffuse = vLightFront;\\n\\t#endif\\n\\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshlambert_vert = \"#define LAMBERT\\nvarying vec3 vLightFront;\\n#ifdef DOUBLE_SIDED\\n\\tvarying vec3 vLightBack;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_frag = \"#define PHONG\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform vec3 specular;\\nuniform float shininess;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\t#include \\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphong_vert = \"#define PHONG\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_frag = \"#define PHYSICAL\\nuniform vec3 diffuse;\\nuniform vec3 emissive;\\nuniform float roughness;\\nuniform float metalness;\\nuniform float opacity;\\n#ifndef STANDARD\\n\\tuniform float clearCoat;\\n\\tuniform float clearCoatRoughness;\\n#endif\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\\n\\tvec3 totalEmissiveRadiance = emissive;\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar meshphysical_vert = \"#define PHYSICAL\\nvarying vec3 vViewPosition;\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\tvViewPosition = - mvPosition.xyz;\\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar normal_frag = \"#define NORMAL\\nuniform float opacity;\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\\n}\\n\";\n\n\tvar normal_vert = \"#define NORMAL\\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvarying vec3 vViewPosition;\\n#endif\\n#ifndef FLAT_SHADED\\n\\tvarying vec3 vNormal;\\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#ifndef FLAT_SHADED\\n\\tvNormal = normalize( transformedNormal );\\n#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\\n\\tvViewPosition = - mvPosition.xyz;\\n#endif\\n}\\n\";\n\n\tvar points_frag = \"uniform vec3 diffuse;\\nuniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\tvec3 outgoingLight = vec3( 0.0 );\\n\\tvec4 diffuseColor = vec4( diffuse, opacity );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\toutgoingLight = diffuseColor.rgb;\\n\\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar points_vert = \"uniform float size;\\nuniform float scale;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#ifdef USE_SIZEATTENUATION\\n\\t\\tgl_PointSize = size * ( scale / - mvPosition.z );\\n\\t#else\\n\\t\\tgl_PointSize = size;\\n\\t#endif\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar shadow_frag = \"uniform float opacity;\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\nvoid main() {\\n\\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\\n}\\n\";\n\n\tvar shadow_vert = \"#include \\nvoid main() {\\n\\t#include \\n\\t#include \\n\\t#include \\n\\t#include \\n}\\n\";\n\n\tvar ShaderChunk = {\n\t\talphamap_fragment: alphamap_fragment,\n\t\talphamap_pars_fragment: alphamap_pars_fragment,\n\t\talphatest_fragment: alphatest_fragment,\n\t\taomap_fragment: aomap_fragment,\n\t\taomap_pars_fragment: aomap_pars_fragment,\n\t\tbegin_vertex: begin_vertex,\n\t\tbeginnormal_vertex: beginnormal_vertex,\n\t\tbsdfs: bsdfs,\n\t\tbumpmap_pars_fragment: bumpmap_pars_fragment,\n\t\tclipping_planes_fragment: clipping_planes_fragment,\n\t\tclipping_planes_pars_fragment: clipping_planes_pars_fragment,\n\t\tclipping_planes_pars_vertex: clipping_planes_pars_vertex,\n\t\tclipping_planes_vertex: clipping_planes_vertex,\n\t\tcolor_fragment: color_fragment,\n\t\tcolor_pars_fragment: color_pars_fragment,\n\t\tcolor_pars_vertex: color_pars_vertex,\n\t\tcolor_vertex: color_vertex,\n\t\tcommon: common,\n\t\tcube_uv_reflection_fragment: cube_uv_reflection_fragment,\n\t\tdefaultnormal_vertex: defaultnormal_vertex,\n\t\tdisplacementmap_pars_vertex: displacementmap_pars_vertex,\n\t\tdisplacementmap_vertex: displacementmap_vertex,\n\t\temissivemap_fragment: emissivemap_fragment,\n\t\temissivemap_pars_fragment: emissivemap_pars_fragment,\n\t\tencodings_fragment: encodings_fragment,\n\t\tencodings_pars_fragment: encodings_pars_fragment,\n\t\tenvmap_fragment: envmap_fragment,\n\t\tenvmap_pars_fragment: envmap_pars_fragment,\n\t\tenvmap_pars_vertex: envmap_pars_vertex,\n\t\tenvmap_vertex: envmap_vertex,\n\t\tfog_vertex: fog_vertex,\n\t\tfog_pars_vertex: fog_pars_vertex,\n\t\tfog_fragment: fog_fragment,\n\t\tfog_pars_fragment: fog_pars_fragment,\n\t\tgradientmap_pars_fragment: gradientmap_pars_fragment,\n\t\tlightmap_fragment: lightmap_fragment,\n\t\tlightmap_pars_fragment: lightmap_pars_fragment,\n\t\tlights_lambert_vertex: lights_lambert_vertex,\n\t\tlights_pars: lights_pars,\n\t\tlights_phong_fragment: lights_phong_fragment,\n\t\tlights_phong_pars_fragment: lights_phong_pars_fragment,\n\t\tlights_physical_fragment: lights_physical_fragment,\n\t\tlights_physical_pars_fragment: lights_physical_pars_fragment,\n\t\tlights_template: lights_template,\n\t\tlogdepthbuf_fragment: logdepthbuf_fragment,\n\t\tlogdepthbuf_pars_fragment: logdepthbuf_pars_fragment,\n\t\tlogdepthbuf_pars_vertex: logdepthbuf_pars_vertex,\n\t\tlogdepthbuf_vertex: logdepthbuf_vertex,\n\t\tmap_fragment: map_fragment,\n\t\tmap_pars_fragment: map_pars_fragment,\n\t\tmap_particle_fragment: map_particle_fragment,\n\t\tmap_particle_pars_fragment: map_particle_pars_fragment,\n\t\tmetalnessmap_fragment: metalnessmap_fragment,\n\t\tmetalnessmap_pars_fragment: metalnessmap_pars_fragment,\n\t\tmorphnormal_vertex: morphnormal_vertex,\n\t\tmorphtarget_pars_vertex: morphtarget_pars_vertex,\n\t\tmorphtarget_vertex: morphtarget_vertex,\n\t\tnormal_flip: normal_flip,\n\t\tnormal_fragment: normal_fragment,\n\t\tnormalmap_pars_fragment: normalmap_pars_fragment,\n\t\tpacking: packing,\n\t\tpremultiplied_alpha_fragment: premultiplied_alpha_fragment,\n\t\tproject_vertex: project_vertex,\n\t\troughnessmap_fragment: roughnessmap_fragment,\n\t\troughnessmap_pars_fragment: roughnessmap_pars_fragment,\n\t\tshadowmap_pars_fragment: shadowmap_pars_fragment,\n\t\tshadowmap_pars_vertex: shadowmap_pars_vertex,\n\t\tshadowmap_vertex: shadowmap_vertex,\n\t\tshadowmask_pars_fragment: shadowmask_pars_fragment,\n\t\tskinbase_vertex: skinbase_vertex,\n\t\tskinning_pars_vertex: skinning_pars_vertex,\n\t\tskinning_vertex: skinning_vertex,\n\t\tskinnormal_vertex: skinnormal_vertex,\n\t\tspecularmap_fragment: specularmap_fragment,\n\t\tspecularmap_pars_fragment: specularmap_pars_fragment,\n\t\ttonemapping_fragment: tonemapping_fragment,\n\t\ttonemapping_pars_fragment: tonemapping_pars_fragment,\n\t\tuv_pars_fragment: uv_pars_fragment,\n\t\tuv_pars_vertex: uv_pars_vertex,\n\t\tuv_vertex: uv_vertex,\n\t\tuv2_pars_fragment: uv2_pars_fragment,\n\t\tuv2_pars_vertex: uv2_pars_vertex,\n\t\tuv2_vertex: uv2_vertex,\n\t\tworldpos_vertex: worldpos_vertex,\n\n\t\tcube_frag: cube_frag,\n\t\tcube_vert: cube_vert,\n\t\tdepth_frag: depth_frag,\n\t\tdepth_vert: depth_vert,\n\t\tdistanceRGBA_frag: distanceRGBA_frag,\n\t\tdistanceRGBA_vert: distanceRGBA_vert,\n\t\tequirect_frag: equirect_frag,\n\t\tequirect_vert: equirect_vert,\n\t\tlinedashed_frag: linedashed_frag,\n\t\tlinedashed_vert: linedashed_vert,\n\t\tmeshbasic_frag: meshbasic_frag,\n\t\tmeshbasic_vert: meshbasic_vert,\n\t\tmeshlambert_frag: meshlambert_frag,\n\t\tmeshlambert_vert: meshlambert_vert,\n\t\tmeshphong_frag: meshphong_frag,\n\t\tmeshphong_vert: meshphong_vert,\n\t\tmeshphysical_frag: meshphysical_frag,\n\t\tmeshphysical_vert: meshphysical_vert,\n\t\tnormal_frag: normal_frag,\n\t\tnormal_vert: normal_vert,\n\t\tpoints_frag: points_frag,\n\t\tpoints_vert: points_vert,\n\t\tshadow_frag: shadow_frag,\n\t\tshadow_vert: shadow_vert\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Color( r, g, b ) {\n\n\t\tif ( g === undefined && b === undefined ) {\n\n\t\t\t// r is THREE.Color, hex or string\n\t\t\treturn this.set( r );\n\n\t\t}\n\n\t\treturn this.setRGB( r, g, b );\n\n\t}\n\n\tColor.prototype = {\n\n\t\tconstructor: Color,\n\n\t\tisColor: true,\n\n\t\tr: 1, g: 1, b: 1,\n\n\t\tset: function ( value ) {\n\n\t\t\tif ( value && value.isColor ) {\n\n\t\t\t\tthis.copy( value );\n\n\t\t\t} else if ( typeof value === 'number' ) {\n\n\t\t\t\tthis.setHex( value );\n\n\t\t\t} else if ( typeof value === 'string' ) {\n\n\t\t\t\tthis.setStyle( value );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetScalar: function ( scalar ) {\n\n\t\t\tthis.r = scalar;\n\t\t\tthis.g = scalar;\n\t\t\tthis.b = scalar;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHex: function ( hex ) {\n\n\t\t\thex = Math.floor( hex );\n\n\t\t\tthis.r = ( hex >> 16 & 255 ) / 255;\n\t\t\tthis.g = ( hex >> 8 & 255 ) / 255;\n\t\t\tthis.b = ( hex & 255 ) / 255;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetRGB: function ( r, g, b ) {\n\n\t\t\tthis.r = r;\n\t\t\tthis.g = g;\n\t\t\tthis.b = b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetHSL: function () {\n\n\t\t\tfunction hue2rgb( p, q, t ) {\n\n\t\t\t\tif ( t < 0 ) t += 1;\n\t\t\t\tif ( t > 1 ) t -= 1;\n\t\t\t\tif ( t < 1 / 6 ) return p + ( q - p ) * 6 * t;\n\t\t\t\tif ( t < 1 / 2 ) return q;\n\t\t\t\tif ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t );\n\t\t\t\treturn p;\n\n\t\t\t}\n\n\t\t\treturn function setHSL( h, s, l ) {\n\n\t\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\t\t\t\th = _Math.euclideanModulo( h, 1 );\n\t\t\t\ts = _Math.clamp( s, 0, 1 );\n\t\t\t\tl = _Math.clamp( l, 0, 1 );\n\n\t\t\t\tif ( s === 0 ) {\n\n\t\t\t\t\tthis.r = this.g = this.b = l;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );\n\t\t\t\t\tvar q = ( 2 * l ) - p;\n\n\t\t\t\t\tthis.r = hue2rgb( q, p, h + 1 / 3 );\n\t\t\t\t\tthis.g = hue2rgb( q, p, h );\n\t\t\t\t\tthis.b = hue2rgb( q, p, h - 1 / 3 );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetStyle: function ( style ) {\n\n\t\t\tfunction handleAlpha( string ) {\n\n\t\t\t\tif ( string === undefined ) return;\n\n\t\t\t\tif ( parseFloat( string ) < 1 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tvar m;\n\n\t\t\tif ( m = /^((?:rgb|hsl)a?)\\(\\s*([^\\)]*)\\)/.exec( style ) ) {\n\n\t\t\t\t// rgb / hsl\n\n\t\t\t\tvar color;\n\t\t\t\tvar name = m[ 1 ];\n\t\t\t\tvar components = m[ 2 ];\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'rgb':\n\t\t\t\t\tcase 'rgba':\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(255,0,0) rgba(255,0,0,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;\n\t\t\t\t\t\t\tthis.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( color = /^(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)\n\t\t\t\t\t\t\tthis.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;\n\t\t\t\t\t\t\tthis.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'hsl':\n\t\t\t\t\tcase 'hsla':\n\n\t\t\t\t\t\tif ( color = /^([0-9]*\\.?[0-9]+)\\s*,\\s*(\\d+)\\%\\s*,\\s*(\\d+)\\%\\s*(,\\s*([0-9]*\\.?[0-9]+)\\s*)?$/.exec( components ) ) {\n\n\t\t\t\t\t\t\t// hsl(120,50%,50%) hsla(120,50%,50%,0.5)\n\t\t\t\t\t\t\tvar h = parseFloat( color[ 1 ] ) / 360;\n\t\t\t\t\t\t\tvar s = parseInt( color[ 2 ], 10 ) / 100;\n\t\t\t\t\t\t\tvar l = parseInt( color[ 3 ], 10 ) / 100;\n\n\t\t\t\t\t\t\thandleAlpha( color[ 5 ] );\n\n\t\t\t\t\t\t\treturn this.setHSL( h, s, l );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else if ( m = /^\\#([A-Fa-f0-9]+)$/.exec( style ) ) {\n\n\t\t\t\t// hex color\n\n\t\t\t\tvar hex = m[ 1 ];\n\t\t\t\tvar size = hex.length;\n\n\t\t\t\tif ( size === 3 ) {\n\n\t\t\t\t\t// #ff0\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t} else if ( size === 6 ) {\n\n\t\t\t\t\t// #ff0000\n\t\t\t\t\tthis.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;\n\t\t\t\t\tthis.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;\n\t\t\t\t\tthis.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( style && style.length > 0 ) {\n\n\t\t\t\t// color keywords\n\t\t\t\tvar hex = ColorKeywords[ style ];\n\n\t\t\t\tif ( hex !== undefined ) {\n\n\t\t\t\t\t// red\n\t\t\t\t\tthis.setHex( hex );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// unknown color\n\t\t\t\t\tconsole.warn( 'THREE.Color: Unknown color ' + style );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.r, this.g, this.b );\n\n\t\t},\n\n\t\tcopy: function ( color ) {\n\n\t\t\tthis.r = color.r;\n\t\t\tthis.g = color.g;\n\t\t\tthis.b = color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyGammaToLinear: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tthis.r = Math.pow( color.r, gammaFactor );\n\t\t\tthis.g = Math.pow( color.g, gammaFactor );\n\t\t\tthis.b = Math.pow( color.b, gammaFactor );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyLinearToGamma: function ( color, gammaFactor ) {\n\n\t\t\tif ( gammaFactor === undefined ) gammaFactor = 2.0;\n\n\t\t\tvar safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;\n\n\t\t\tthis.r = Math.pow( color.r, safeInverse );\n\t\t\tthis.g = Math.pow( color.g, safeInverse );\n\t\t\tthis.b = Math.pow( color.b, safeInverse );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertGammaToLinear: function () {\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tthis.r = r * r;\n\t\t\tthis.g = g * g;\n\t\t\tthis.b = b * b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconvertLinearToGamma: function () {\n\n\t\t\tthis.r = Math.sqrt( this.r );\n\t\t\tthis.g = Math.sqrt( this.g );\n\t\t\tthis.b = Math.sqrt( this.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetHex: function () {\n\n\t\t\treturn ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;\n\n\t\t},\n\n\t\tgetHexString: function () {\n\n\t\t\treturn ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );\n\n\t\t},\n\n\t\tgetHSL: function ( optionalTarget ) {\n\n\t\t\t// h,s,l ranges are in 0.0 - 1.0\n\n\t\t\tvar hsl = optionalTarget || { h: 0, s: 0, l: 0 };\n\n\t\t\tvar r = this.r, g = this.g, b = this.b;\n\n\t\t\tvar max = Math.max( r, g, b );\n\t\t\tvar min = Math.min( r, g, b );\n\n\t\t\tvar hue, saturation;\n\t\t\tvar lightness = ( min + max ) / 2.0;\n\n\t\t\tif ( min === max ) {\n\n\t\t\t\thue = 0;\n\t\t\t\tsaturation = 0;\n\n\t\t\t} else {\n\n\t\t\t\tvar delta = max - min;\n\n\t\t\t\tsaturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );\n\n\t\t\t\tswitch ( max ) {\n\n\t\t\t\t\tcase r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;\n\t\t\t\t\tcase g: hue = ( b - r ) / delta + 2; break;\n\t\t\t\t\tcase b: hue = ( r - g ) / delta + 4; break;\n\n\t\t\t\t}\n\n\t\t\t\thue /= 6;\n\n\t\t\t}\n\n\t\t\thsl.h = hue;\n\t\t\thsl.s = saturation;\n\t\t\thsl.l = lightness;\n\n\t\t\treturn hsl;\n\n\t\t},\n\n\t\tgetStyle: function () {\n\n\t\t\treturn 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';\n\n\t\t},\n\n\t\toffsetHSL: function ( h, s, l ) {\n\n\t\t\tvar hsl = this.getHSL();\n\n\t\t\thsl.h += h; hsl.s += s; hsl.l += l;\n\n\t\t\tthis.setHSL( hsl.h, hsl.s, hsl.l );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( color ) {\n\n\t\t\tthis.r += color.r;\n\t\t\tthis.g += color.g;\n\t\t\tthis.b += color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddColors: function ( color1, color2 ) {\n\n\t\t\tthis.r = color1.r + color2.r;\n\t\t\tthis.g = color1.g + color2.g;\n\t\t\tthis.b = color1.b + color2.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddScalar: function ( s ) {\n\n\t\t\tthis.r += s;\n\t\t\tthis.g += s;\n\t\t\tthis.b += s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsub: function( color ) {\n\n\t\t\tthis.r = Math.max( 0, this.r - color.r );\n\t\t\tthis.g = Math.max( 0, this.g - color.g );\n\t\t\tthis.b = Math.max( 0, this.b - color.b );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiply: function ( color ) {\n\n\t\t\tthis.r *= color.r;\n\t\t\tthis.g *= color.g;\n\t\t\tthis.b *= color.b;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tthis.r *= s;\n\t\t\tthis.g *= s;\n\t\t\tthis.b *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tlerp: function ( color, alpha ) {\n\n\t\t\tthis.r += ( color.r - this.r ) * alpha;\n\t\t\tthis.g += ( color.g - this.g ) * alpha;\n\t\t\tthis.b += ( color.b - this.b ) * alpha;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( c ) {\n\n\t\t\treturn ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.r = array[ offset ];\n\t\t\tthis.g = array[ offset + 1 ];\n\t\t\tthis.b = array[ offset + 2 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this.r;\n\t\t\tarray[ offset + 1 ] = this.g;\n\t\t\tarray[ offset + 2 ] = this.b;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\treturn this.getHex();\n\n\t\t}\n\n\t};\n\n\tvar ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,\n\t'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,\n\t'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,\n\t'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,\n\t'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,\n\t'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,\n\t'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,\n\t'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,\n\t'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,\n\t'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,\n\t'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,\n\t'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,\n\t'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,\n\t'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,\n\t'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,\n\t'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,\n\t'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,\n\t'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,\n\t'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,\n\t'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,\n\t'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,\n\t'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,\n\t'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,\n\t'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { data: data, width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.generateMipmaps = false;\n\t\tthis.flipY = false;\n\t\tthis.unpackAlignment = 1;\n\n\t}\n\n\tDataTexture.prototype = Object.create( Texture.prototype );\n\tDataTexture.prototype.constructor = DataTexture;\n\n\tDataTexture.prototype.isDataTexture = true;\n\n\t/**\n\t * Uniforms library for shared webgl shaders\n\t */\n\n\tvar UniformsLib = {\n\n\t\tcommon: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },\n\n\t\t\tspecularMap: { value: null },\n\t\t\talphaMap: { value: null },\n\n\t\t\tenvMap: { value: null },\n\t\t\tflipEnvMap: { value: - 1 },\n\t\t\treflectivity: { value: 1.0 },\n\t\t\trefractionRatio: { value: 0.98 }\n\n\t\t},\n\n\t\taomap: {\n\n\t\t\taoMap: { value: null },\n\t\t\taoMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\tlightmap: {\n\n\t\t\tlightMap: { value: null },\n\t\t\tlightMapIntensity: { value: 1 }\n\n\t\t},\n\n\t\temissivemap: {\n\n\t\t\temissiveMap: { value: null }\n\n\t\t},\n\n\t\tbumpmap: {\n\n\t\t\tbumpMap: { value: null },\n\t\t\tbumpScale: { value: 1 }\n\n\t\t},\n\n\t\tnormalmap: {\n\n\t\t\tnormalMap: { value: null },\n\t\t\tnormalScale: { value: new Vector2( 1, 1 ) }\n\n\t\t},\n\n\t\tdisplacementmap: {\n\n\t\t\tdisplacementMap: { value: null },\n\t\t\tdisplacementScale: { value: 1 },\n\t\t\tdisplacementBias: { value: 0 }\n\n\t\t},\n\n\t\troughnessmap: {\n\n\t\t\troughnessMap: { value: null }\n\n\t\t},\n\n\t\tmetalnessmap: {\n\n\t\t\tmetalnessMap: { value: null }\n\n\t\t},\n\n\t\tgradientmap: {\n\n\t\t\tgradientMap: { value: null }\n\n\t\t},\n\n\t\tfog: {\n\n\t\t\tfogDensity: { value: 0.00025 },\n\t\t\tfogNear: { value: 1 },\n\t\t\tfogFar: { value: 2000 },\n\t\t\tfogColor: { value: new Color( 0xffffff ) }\n\n\t\t},\n\n\t\tlights: {\n\n\t\t\tambientLightColor: { value: [] },\n\n\t\t\tdirectionalLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tcolor: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tdirectionalShadowMap: { value: [] },\n\t\t\tdirectionalShadowMatrix: { value: [] },\n\n\t\t\tspotLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdirection: {},\n\t\t\t\tdistance: {},\n\t\t\t\tconeCos: {},\n\t\t\t\tpenumbraCos: {},\n\t\t\t\tdecay: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tspotShadowMap: { value: [] },\n\t\t\tspotShadowMatrix: { value: [] },\n\n\t\t\tpointLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\tdecay: {},\n\t\t\t\tdistance: {},\n\n\t\t\t\tshadow: {},\n\t\t\t\tshadowBias: {},\n\t\t\t\tshadowRadius: {},\n\t\t\t\tshadowMapSize: {}\n\t\t\t} },\n\n\t\t\tpointShadowMap: { value: [] },\n\t\t\tpointShadowMatrix: { value: [] },\n\n\t\t\themisphereLights: { value: [], properties: {\n\t\t\t\tdirection: {},\n\t\t\t\tskyColor: {},\n\t\t\t\tgroundColor: {}\n\t\t\t} },\n\n\t\t\t// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src\n\t\t\trectAreaLights: { value: [], properties: {\n\t\t\t\tcolor: {},\n\t\t\t\tposition: {},\n\t\t\t\twidth: {},\n\t\t\t\theight: {}\n\t\t\t} }\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tdiffuse: { value: new Color( 0xeeeeee ) },\n\t\t\topacity: { value: 1.0 },\n\t\t\tsize: { value: 1.0 },\n\t\t\tscale: { value: 1.0 },\n\t\t\tmap: { value: null },\n\t\t\toffsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t */\n\n\tvar ShaderLib = {\n\n\t\tbasic: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshbasic_vert,\n\t\t\tfragmentShader: ShaderChunk.meshbasic_frag\n\n\t\t},\n\n\t\tlambert: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshlambert_vert,\n\t\t\tfragmentShader: ShaderChunk.meshlambert_frag\n\n\t\t},\n\n\t\tphong: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.gradientmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\tspecular: { value: new Color( 0x111111 ) },\n\t\t\t\t\tshininess: { value: 30 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphong_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphong_frag\n\n\t\t},\n\n\t\tstandard: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.aomap,\n\t\t\t\tUniformsLib.lightmap,\n\t\t\t\tUniformsLib.emissivemap,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\tUniformsLib.roughnessmap,\n\t\t\t\tUniformsLib.metalnessmap,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\temissive: { value: new Color( 0x000000 ) },\n\t\t\t\t\troughness: { value: 0.5 },\n\t\t\t\t\tmetalness: { value: 0 },\n\t\t\t\t\tenvMapIntensity: { value: 1 } // temporary\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t\t},\n\n\t\tpoints: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.points,\n\t\t\t\tUniformsLib.fog\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.points_vert,\n\t\t\tfragmentShader: ShaderChunk.points_frag\n\n\t\t},\n\n\t\tdashed: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.fog,\n\t\t\t\t{\n\t\t\t\t\tscale: { value: 1 },\n\t\t\t\t\tdashSize: { value: 1 },\n\t\t\t\t\ttotalSize: { value: 2 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.linedashed_vert,\n\t\t\tfragmentShader: ShaderChunk.linedashed_frag\n\n\t\t},\n\n\t\tdepth: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.displacementmap\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.depth_vert,\n\t\t\tfragmentShader: ShaderChunk.depth_frag\n\n\t\t},\n\n\t\tnormal: {\n\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.common,\n\t\t\t\tUniformsLib.bumpmap,\n\t\t\t\tUniformsLib.normalmap,\n\t\t\t\tUniformsLib.displacementmap,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\n\t\t\tvertexShader: ShaderChunk.normal_vert,\n\t\t\tfragmentShader: ShaderChunk.normal_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tcube: {\n\n\t\t\tuniforms: {\n\t\t\t\ttCube: { value: null },\n\t\t\t\ttFlip: { value: - 1 },\n\t\t\t\topacity: { value: 1.0 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.cube_vert,\n\t\t\tfragmentShader: ShaderChunk.cube_frag\n\n\t\t},\n\n\t\t/* -------------------------------------------------------------------------\n\t\t//\tCube map shader\n\t\t ------------------------------------------------------------------------- */\n\n\t\tequirect: {\n\n\t\t\tuniforms: {\n\t\t\t\ttEquirect: { value: null },\n\t\t\t\ttFlip: { value: - 1 }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.equirect_vert,\n\t\t\tfragmentShader: ShaderChunk.equirect_frag\n\n\t\t},\n\n\t\tdistanceRGBA: {\n\n\t\t\tuniforms: {\n\t\t\t\tlightPos: { value: new Vector3() }\n\t\t\t},\n\n\t\t\tvertexShader: ShaderChunk.distanceRGBA_vert,\n\t\t\tfragmentShader: ShaderChunk.distanceRGBA_frag\n\n\t\t}\n\n\t};\n\n\tShaderLib.physical = {\n\n\t\tuniforms: UniformsUtils.merge( [\n\t\t\tShaderLib.standard.uniforms,\n\t\t\t{\n\t\t\t\tclearCoat: { value: 0 },\n\t\t\t\tclearCoatRoughness: { value: 0 }\n\t\t\t}\n\t\t] ),\n\n\t\tvertexShader: ShaderChunk.meshphysical_vert,\n\t\tfragmentShader: ShaderChunk.meshphysical_frag\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Box2( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );\n\n\t}\n\n\tBox2.prototype = {\n\n\t\tconstructor: Box2,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = + Infinity;\n\t\t\tthis.max.x = this.max.y = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ? false : true;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector2();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector2();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlarePlugin( renderer, flares ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar shader, program, attributes, uniforms;\n\n\t\tvar tempTexture, occlusionTexture;\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 1, - 1, 0, 0,\n\t\t\t\t 1, - 1, 1, 0,\n\t\t\t\t 1, 1, 1, 1,\n\t\t\t\t- 1, 1, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\t// buffers\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\t// textures\n\n\t\t\ttempTexture = gl.createTexture();\n\t\t\tocclusionTexture = gl.createTexture();\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\tgl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\n\t\t\tshader = {\n\n\t\t\t\tvertexShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform vec3 screenPosition;\",\n\t\t\t\t\t\"uniform vec2 scale;\",\n\t\t\t\t\t\"uniform float rotation;\",\n\n\t\t\t\t\t\"uniform sampler2D occlusionMap;\",\n\n\t\t\t\t\t\"attribute vec2 position;\",\n\t\t\t\t\t\"attribute vec2 uv;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t\"vUV = uv;\",\n\n\t\t\t\t\t\t\"vec2 pos = position;\",\n\n\t\t\t\t\t\t\"if ( renderType == 2 ) {\",\n\n\t\t\t\t\t\t\t\"vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\",\n\t\t\t\t\t\t\t\"visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\",\n\n\t\t\t\t\t\t\t\"vVisibility = visibility.r / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.g / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= visibility.b / 9.0;\",\n\t\t\t\t\t\t\t\"vVisibility *= 1.0 - visibility.a / 9.0;\",\n\n\t\t\t\t\t\t\t\"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\",\n\t\t\t\t\t\t\t\"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\t\"gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" ),\n\n\t\t\t\tfragmentShader: [\n\n\t\t\t\t\t\"uniform lowp int renderType;\",\n\n\t\t\t\t\t\"uniform sampler2D map;\",\n\t\t\t\t\t\"uniform float opacity;\",\n\t\t\t\t\t\"uniform vec3 color;\",\n\n\t\t\t\t\t\"varying vec2 vUV;\",\n\t\t\t\t\t\"varying float vVisibility;\",\n\n\t\t\t\t\t\"void main() {\",\n\n\t\t\t\t\t\t// pink square\n\n\t\t\t\t\t\t\"if ( renderType == 0 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\",\n\n\t\t\t\t\t\t// restore\n\n\t\t\t\t\t\t\"} else if ( renderType == 1 ) {\",\n\n\t\t\t\t\t\t\t\"gl_FragColor = texture2D( map, vUV );\",\n\n\t\t\t\t\t\t// flare\n\n\t\t\t\t\t\t\"} else {\",\n\n\t\t\t\t\t\t\t\"vec4 texture = texture2D( map, vUV );\",\n\t\t\t\t\t\t\t\"texture.a *= opacity * vVisibility;\",\n\t\t\t\t\t\t\t\"gl_FragColor = texture;\",\n\t\t\t\t\t\t\t\"gl_FragColor.rgb *= color;\",\n\n\t\t\t\t\t\t\"}\",\n\n\t\t\t\t\t\"}\"\n\n\t\t\t\t].join( \"\\n\" )\n\n\t\t\t};\n\n\t\t\tprogram = createProgram( shader );\n\n\t\t\tattributes = {\n\t\t\t\tvertex: gl.getAttribLocation ( program, \"position\" ),\n\t\t\t\tuv: gl.getAttribLocation ( program, \"uv\" )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\trenderType: gl.getUniformLocation( program, \"renderType\" ),\n\t\t\t\tmap: gl.getUniformLocation( program, \"map\" ),\n\t\t\t\tocclusionMap: gl.getUniformLocation( program, \"occlusionMap\" ),\n\t\t\t\topacity: gl.getUniformLocation( program, \"opacity\" ),\n\t\t\t\tcolor: gl.getUniformLocation( program, \"color\" ),\n\t\t\t\tscale: gl.getUniformLocation( program, \"scale\" ),\n\t\t\t\trotation: gl.getUniformLocation( program, \"rotation\" ),\n\t\t\t\tscreenPosition: gl.getUniformLocation( program, \"screenPosition\" )\n\t\t\t};\n\n\t\t}\n\n\t\t/*\n\t\t * Render lens flares\n\t\t * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,\n\t\t * reads these back and calculates occlusion.\n\t\t */\n\n\t\tthis.render = function ( scene, camera, viewport ) {\n\n\t\t\tif ( flares.length === 0 ) return;\n\n\t\t\tvar tempPosition = new Vector3();\n\n\t\t\tvar invAspect = viewport.w / viewport.z,\n\t\t\t\thalfViewportWidth = viewport.z * 0.5,\n\t\t\t\thalfViewportHeight = viewport.w * 0.5;\n\n\t\t\tvar size = 16 / viewport.w,\n\t\t\t\tscale = new Vector2( size * invAspect, size );\n\n\t\t\tvar screenPosition = new Vector3( 1, 1, 0 ),\n\t\t\t\tscreenPositionPixels = new Vector2( 1, 1 );\n\n\t\t\tvar validArea = new Box2();\n\n\t\t\tvalidArea.min.set( viewport.x, viewport.y );\n\t\t\tvalidArea.max.set( viewport.x + ( viewport.z - 16 ), viewport.y + ( viewport.w - 16 ) );\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.vertex );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t// loop through all lens flares to update their occlusion and positions\n\t\t\t// setup gl and common used attribs/uniforms\n\n\t\t\tgl.uniform1i( uniforms.occlusionMap, 0 );\n\t\t\tgl.uniform1i( uniforms.map, 1 );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.vertex, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.setDepthWrite( false );\n\n\t\t\tfor ( var i = 0, l = flares.length; i < l; i ++ ) {\n\n\t\t\t\tsize = 16 / viewport.w;\n\t\t\t\tscale.set( size * invAspect, size );\n\n\t\t\t\t// calc object screen position\n\n\t\t\t\tvar flare = flares[ i ];\n\n\t\t\t\ttempPosition.set( flare.matrixWorld.elements[ 12 ], flare.matrixWorld.elements[ 13 ], flare.matrixWorld.elements[ 14 ] );\n\n\t\t\t\ttempPosition.applyMatrix4( camera.matrixWorldInverse );\n\t\t\t\ttempPosition.applyMatrix4( camera.projectionMatrix );\n\n\t\t\t\t// setup arrays for gl programs\n\n\t\t\t\tscreenPosition.copy( tempPosition );\n\n\t\t\t\t// horizontal and vertical coordinate of the lower left corner of the pixels to copy\n\n\t\t\t\tscreenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8;\n\t\t\t\tscreenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8;\n\n\t\t\t\t// screen cull\n\n\t\t\t\tif ( validArea.containsPoint( screenPositionPixels ) === true ) {\n\n\t\t\t\t\t// save current RGB to temp texture\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, null );\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// render pink quad\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\n\t\t\t\t\tstate.disable( gl.BLEND );\n\t\t\t\t\tstate.enable( gl.DEPTH_TEST );\n\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// copy result to occlusionMap\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, occlusionTexture );\n\t\t\t\t\tgl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 );\n\n\n\t\t\t\t\t// restore graphics\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 1 );\n\t\t\t\t\tstate.disable( gl.DEPTH_TEST );\n\n\t\t\t\t\tstate.activeTexture( gl.TEXTURE1 );\n\t\t\t\t\tstate.bindTexture( gl.TEXTURE_2D, tempTexture );\n\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\n\t\t\t\t\t// update object positions\n\n\t\t\t\t\tflare.positionScreen.copy( screenPosition );\n\n\t\t\t\t\tif ( flare.customUpdateCallback ) {\n\n\t\t\t\t\t\tflare.customUpdateCallback( flare );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tflare.updateLensFlares();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// render flares\n\n\t\t\t\t\tgl.uniform1i( uniforms.renderType, 2 );\n\t\t\t\t\tstate.enable( gl.BLEND );\n\n\t\t\t\t\tfor ( var j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar sprite = flare.lensFlares[ j ];\n\n\t\t\t\t\t\tif ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {\n\n\t\t\t\t\t\t\tscreenPosition.x = sprite.x;\n\t\t\t\t\t\t\tscreenPosition.y = sprite.y;\n\t\t\t\t\t\t\tscreenPosition.z = sprite.z;\n\n\t\t\t\t\t\t\tsize = sprite.size * sprite.scale / viewport.w;\n\n\t\t\t\t\t\t\tscale.x = size * invAspect;\n\t\t\t\t\t\t\tscale.y = size;\n\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );\n\t\t\t\t\t\t\tgl.uniform2f( uniforms.scale, scale.x, scale.y );\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.rotation, sprite.rotation );\n\n\t\t\t\t\t\t\tgl.uniform1f( uniforms.opacity, sprite.opacity );\n\t\t\t\t\t\t\tgl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );\n\n\t\t\t\t\t\t\tstate.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );\n\t\t\t\t\t\t\trenderer.setTexture2D( sprite.texture, 1 );\n\n\t\t\t\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.DEPTH_TEST );\n\t\t\tstate.setDepthWrite( true );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram( shader ) {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\n\t\t\tvar prefix = \"precision \" + renderer.getPrecision() + \" float;\\n\";\n\n\t\t\tgl.shaderSource( fragmentShader, prefix + shader.fragmentShader );\n\t\t\tgl.shaderSource( vertexShader, prefix + shader.vertexShader );\n\n\t\t\tgl.compileShader( fragmentShader );\n\t\t\tgl.compileShader( vertexShader );\n\n\t\t\tgl.attachShader( program, fragmentShader );\n\t\t\tgl.attachShader( program, vertexShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpritePlugin( renderer, sprites ) {\n\n\t\tvar gl = renderer.context;\n\t\tvar state = renderer.state;\n\n\t\tvar vertexBuffer, elementBuffer;\n\t\tvar program, attributes, uniforms;\n\n\t\tvar texture;\n\n\t\t// decompose matrixWorld\n\n\t\tvar spritePosition = new Vector3();\n\t\tvar spriteRotation = new Quaternion();\n\t\tvar spriteScale = new Vector3();\n\n\t\tfunction init() {\n\n\t\t\tvar vertices = new Float32Array( [\n\t\t\t\t- 0.5, - 0.5, 0, 0,\n\t\t\t\t 0.5, - 0.5, 1, 0,\n\t\t\t\t 0.5, 0.5, 1, 1,\n\t\t\t\t- 0.5, 0.5, 0, 1\n\t\t\t] );\n\n\t\t\tvar faces = new Uint16Array( [\n\t\t\t\t0, 1, 2,\n\t\t\t\t0, 2, 3\n\t\t\t] );\n\n\t\t\tvertexBuffer = gl.createBuffer();\n\t\t\telementBuffer = gl.createBuffer();\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\t\t\tgl.bufferData( gl.ELEMENT_ARRAY_BUFFER, faces, gl.STATIC_DRAW );\n\n\t\t\tprogram = createProgram();\n\n\t\t\tattributes = {\n\t\t\t\tposition:\t\t\tgl.getAttribLocation ( program, 'position' ),\n\t\t\t\tuv:\t\t\t\t\tgl.getAttribLocation ( program, 'uv' )\n\t\t\t};\n\n\t\t\tuniforms = {\n\t\t\t\tuvOffset:\t\t\tgl.getUniformLocation( program, 'uvOffset' ),\n\t\t\t\tuvScale:\t\t\tgl.getUniformLocation( program, 'uvScale' ),\n\n\t\t\t\trotation:\t\t\tgl.getUniformLocation( program, 'rotation' ),\n\t\t\t\tscale:\t\t\t\tgl.getUniformLocation( program, 'scale' ),\n\n\t\t\t\tcolor:\t\t\t\tgl.getUniformLocation( program, 'color' ),\n\t\t\t\tmap:\t\t\t\tgl.getUniformLocation( program, 'map' ),\n\t\t\t\topacity:\t\t\tgl.getUniformLocation( program, 'opacity' ),\n\n\t\t\t\tmodelViewMatrix: \tgl.getUniformLocation( program, 'modelViewMatrix' ),\n\t\t\t\tprojectionMatrix:\tgl.getUniformLocation( program, 'projectionMatrix' ),\n\n\t\t\t\tfogType:\t\t\tgl.getUniformLocation( program, 'fogType' ),\n\t\t\t\tfogDensity:\t\t\tgl.getUniformLocation( program, 'fogDensity' ),\n\t\t\t\tfogNear:\t\t\tgl.getUniformLocation( program, 'fogNear' ),\n\t\t\t\tfogFar:\t\t\t\tgl.getUniformLocation( program, 'fogFar' ),\n\t\t\t\tfogColor:\t\t\tgl.getUniformLocation( program, 'fogColor' ),\n\n\t\t\t\talphaTest:\t\t\tgl.getUniformLocation( program, 'alphaTest' )\n\t\t\t};\n\n\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\tcanvas.width = 8;\n\t\t\tcanvas.height = 8;\n\n\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\tcontext.fillStyle = 'white';\n\t\t\tcontext.fillRect( 0, 0, 8, 8 );\n\n\t\t\ttexture = new Texture( canvas );\n\t\t\ttexture.needsUpdate = true;\n\n\t\t}\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( sprites.length === 0 ) return;\n\n\t\t\t// setup gl\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tinit();\n\n\t\t\t}\n\n\t\t\tgl.useProgram( program );\n\n\t\t\tstate.initAttributes();\n\t\t\tstate.enableAttribute( attributes.position );\n\t\t\tstate.enableAttribute( attributes.uv );\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\tstate.disable( gl.CULL_FACE );\n\t\t\tstate.enable( gl.BLEND );\n\n\t\t\tgl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );\n\t\t\tgl.vertexAttribPointer( attributes.position, 2, gl.FLOAT, false, 2 * 8, 0 );\n\t\t\tgl.vertexAttribPointer( attributes.uv, 2, gl.FLOAT, false, 2 * 8, 8 );\n\n\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, elementBuffer );\n\n\t\t\tgl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );\n\n\t\t\tstate.activeTexture( gl.TEXTURE0 );\n\t\t\tgl.uniform1i( uniforms.map, 0 );\n\n\t\t\tvar oldFogType = 0;\n\t\t\tvar sceneFogType = 0;\n\t\t\tvar fog = scene.fog;\n\n\t\t\tif ( fog ) {\n\n\t\t\t\tgl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );\n\n\t\t\t\tif ( fog.isFog ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogNear, fog.near );\n\t\t\t\t\tgl.uniform1f( uniforms.fogFar, fog.far );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 1 );\n\t\t\t\t\toldFogType = 1;\n\t\t\t\t\tsceneFogType = 1;\n\n\t\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\t\tgl.uniform1f( uniforms.fogDensity, fog.density );\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, 2 );\n\t\t\t\t\toldFogType = 2;\n\t\t\t\t\tsceneFogType = 2;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tgl.uniform1i( uniforms.fogType, 0 );\n\t\t\t\toldFogType = 0;\n\t\t\t\tsceneFogType = 0;\n\n\t\t\t}\n\n\n\t\t\t// update positions and sort\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\n\t\t\t\tsprite.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );\n\t\t\t\tsprite.z = - sprite.modelViewMatrix.elements[ 14 ];\n\n\t\t\t}\n\n\t\t\tsprites.sort( painterSortStable );\n\n\t\t\t// render all sprites\n\n\t\t\tvar scale = [];\n\n\t\t\tfor ( var i = 0, l = sprites.length; i < l; i ++ ) {\n\n\t\t\t\tvar sprite = sprites[ i ];\n\t\t\t\tvar material = sprite.material;\n\n\t\t\t\tif ( material.visible === false ) continue;\n\n\t\t\t\tgl.uniform1f( uniforms.alphaTest, material.alphaTest );\n\t\t\t\tgl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite.modelViewMatrix.elements );\n\n\t\t\t\tsprite.matrixWorld.decompose( spritePosition, spriteRotation, spriteScale );\n\n\t\t\t\tscale[ 0 ] = spriteScale.x;\n\t\t\t\tscale[ 1 ] = spriteScale.y;\n\n\t\t\t\tvar fogType = 0;\n\n\t\t\t\tif ( scene.fog && material.fog ) {\n\n\t\t\t\t\tfogType = sceneFogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( oldFogType !== fogType ) {\n\n\t\t\t\t\tgl.uniform1i( uniforms.fogType, fogType );\n\t\t\t\t\toldFogType = fogType;\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.map !== null ) {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.uniform2f( uniforms.uvOffset, 0, 0 );\n\t\t\t\t\tgl.uniform2f( uniforms.uvScale, 1, 1 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.uniform1f( uniforms.opacity, material.opacity );\n\t\t\t\tgl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );\n\n\t\t\t\tgl.uniform1f( uniforms.rotation, material.rotation );\n\t\t\t\tgl.uniform2fv( uniforms.scale, scale );\n\n\t\t\t\tstate.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );\n\t\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\t\tstate.setDepthWrite( material.depthWrite );\n\n\t\t\t\tif ( material.map ) {\n\n\t\t\t\t\trenderer.setTexture2D( material.map, 0 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setTexture2D( texture, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tgl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );\n\n\t\t\t}\n\n\t\t\t// restore gl\n\n\t\t\tstate.enable( gl.CULL_FACE );\n\n\t\t\trenderer.resetGLState();\n\n\t\t};\n\n\t\tfunction createProgram() {\n\n\t\t\tvar program = gl.createProgram();\n\n\t\t\tvar vertexShader = gl.createShader( gl.VERTEX_SHADER );\n\t\t\tvar fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );\n\n\t\t\tgl.shaderSource( vertexShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform float rotation;',\n\t\t\t\t'uniform vec2 scale;',\n\t\t\t\t'uniform vec2 uvOffset;',\n\t\t\t\t'uniform vec2 uvScale;',\n\n\t\t\t\t'attribute vec2 position;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vUV = uvOffset + uv * uvScale;',\n\n\t\t\t\t\t'vec2 alignedPosition = position * scale;',\n\n\t\t\t\t\t'vec2 rotatedPosition;',\n\t\t\t\t\t'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',\n\t\t\t\t\t'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',\n\n\t\t\t\t\t'vec4 finalPosition;',\n\n\t\t\t\t\t'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',\n\t\t\t\t\t'finalPosition.xy += rotatedPosition;',\n\t\t\t\t\t'finalPosition = projectionMatrix * finalPosition;',\n\n\t\t\t\t\t'gl_Position = finalPosition;',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.shaderSource( fragmentShader, [\n\n\t\t\t\t'precision ' + renderer.getPrecision() + ' float;',\n\n\t\t\t\t'uniform vec3 color;',\n\t\t\t\t'uniform sampler2D map;',\n\t\t\t\t'uniform float opacity;',\n\n\t\t\t\t'uniform int fogType;',\n\t\t\t\t'uniform vec3 fogColor;',\n\t\t\t\t'uniform float fogDensity;',\n\t\t\t\t'uniform float fogNear;',\n\t\t\t\t'uniform float fogFar;',\n\t\t\t\t'uniform float alphaTest;',\n\n\t\t\t\t'varying vec2 vUV;',\n\n\t\t\t\t'void main() {',\n\n\t\t\t\t\t'vec4 texture = texture2D( map, vUV );',\n\n\t\t\t\t\t'if ( texture.a < alphaTest ) discard;',\n\n\t\t\t\t\t'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',\n\n\t\t\t\t\t'if ( fogType > 0 ) {',\n\n\t\t\t\t\t\t'float depth = gl_FragCoord.z / gl_FragCoord.w;',\n\t\t\t\t\t\t'float fogFactor = 0.0;',\n\n\t\t\t\t\t\t'if ( fogType == 1 ) {',\n\n\t\t\t\t\t\t\t'fogFactor = smoothstep( fogNear, fogFar, depth );',\n\n\t\t\t\t\t\t'} else {',\n\n\t\t\t\t\t\t\t'const float LOG2 = 1.442695;',\n\t\t\t\t\t\t\t'fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',\n\t\t\t\t\t\t\t'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',\n\n\t\t\t\t\t\t'}',\n\n\t\t\t\t\t\t'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',\n\n\t\t\t\t\t'}',\n\n\t\t\t\t'}'\n\n\t\t\t].join( '\\n' ) );\n\n\t\t\tgl.compileShader( vertexShader );\n\t\t\tgl.compileShader( fragmentShader );\n\n\t\t\tgl.attachShader( program, vertexShader );\n\t\t\tgl.attachShader( program, fragmentShader );\n\n\t\t\tgl.linkProgram( program );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.renderOrder !== b.renderOrder ) {\n\n\t\t\t\treturn a.renderOrder - b.renderOrder;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn b.id - a.id;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar materialId = 0;\n\n\tfunction Material() {\n\n\t\tObject.defineProperty( this, 'id', { value: materialId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Material';\n\n\t\tthis.fog = true;\n\t\tthis.lights = true;\n\n\t\tthis.blending = NormalBlending;\n\t\tthis.side = FrontSide;\n\t\tthis.shading = SmoothShading; // THREE.FlatShading, THREE.SmoothShading\n\t\tthis.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors\n\n\t\tthis.opacity = 1;\n\t\tthis.transparent = false;\n\n\t\tthis.blendSrc = SrcAlphaFactor;\n\t\tthis.blendDst = OneMinusSrcAlphaFactor;\n\t\tthis.blendEquation = AddEquation;\n\t\tthis.blendSrcAlpha = null;\n\t\tthis.blendDstAlpha = null;\n\t\tthis.blendEquationAlpha = null;\n\n\t\tthis.depthFunc = LessEqualDepth;\n\t\tthis.depthTest = true;\n\t\tthis.depthWrite = true;\n\n\t\tthis.clippingPlanes = null;\n\t\tthis.clipIntersection = false;\n\t\tthis.clipShadows = false;\n\n\t\tthis.colorWrite = true;\n\n\t\tthis.precision = null; // override the renderer's default precision for this material\n\n\t\tthis.polygonOffset = false;\n\t\tthis.polygonOffsetFactor = 0;\n\t\tthis.polygonOffsetUnits = 0;\n\n\t\tthis.alphaTest = 0;\n\t\tthis.premultipliedAlpha = false;\n\n\t\tthis.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer\n\n\t\tthis.visible = true;\n\n\t\tthis._needsUpdate = true;\n\n\t}\n\n\tMaterial.prototype = {\n\n\t\tconstructor: Material,\n\n\t\tisMaterial: true,\n\n\t\tget needsUpdate() {\n\n\t\t\treturn this._needsUpdate;\n\n\t\t},\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.update();\n\t\t\tthis._needsUpdate = value;\n\n\t\t},\n\n\t\tsetValues: function ( values ) {\n\n\t\t\tif ( values === undefined ) return;\n\n\t\t\tfor ( var key in values ) {\n\n\t\t\t\tvar newValue = values[ key ];\n\n\t\t\t\tif ( newValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.Material: '\" + key + \"' parameter is undefined.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar currentValue = this[ key ];\n\n\t\t\t\tif ( currentValue === undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.\" + this.type + \": '\" + key + \"' is not a property of this material.\" );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tif ( currentValue && currentValue.isColor ) {\n\n\t\t\t\t\tcurrentValue.set( newValue );\n\n\t\t\t\t} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {\n\n\t\t\t\t\tcurrentValue.copy( newValue );\n\n\t\t\t\t} else if ( key === 'overdraw' ) {\n\n\t\t\t\t\t// ensure overdraw is backwards-compatible with legacy boolean type\n\t\t\t\t\tthis[ key ] = Number( newValue );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis[ key ] = newValue;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar isRoot = meta === undefined;\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tmeta = {\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Material',\n\t\t\t\t\tgenerator: 'Material.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Material serialization\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.color && this.color.isColor ) data.color = this.color.getHex();\n\n\t\t\tif ( this.roughness !== undefined ) data.roughness = this.roughness;\n\t\t\tif ( this.metalness !== undefined ) data.metalness = this.metalness;\n\n\t\t\tif ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();\n\t\t\tif ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();\n\t\t\tif ( this.shininess !== undefined ) data.shininess = this.shininess;\n\t\t\tif ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;\n\t\t\tif ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;\n\n\t\t\tif ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;\n\t\t\tif ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;\n\t\t\tif ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;\n\t\t\tif ( this.bumpMap && this.bumpMap.isTexture ) {\n\n\t\t\t\tdata.bumpMap = this.bumpMap.toJSON( meta ).uuid;\n\t\t\t\tdata.bumpScale = this.bumpScale;\n\n\t\t\t}\n\t\t\tif ( this.normalMap && this.normalMap.isTexture ) {\n\n\t\t\t\tdata.normalMap = this.normalMap.toJSON( meta ).uuid;\n\t\t\t\tdata.normalScale = this.normalScale.toArray();\n\n\t\t\t}\n\t\t\tif ( this.displacementMap && this.displacementMap.isTexture ) {\n\n\t\t\t\tdata.displacementMap = this.displacementMap.toJSON( meta ).uuid;\n\t\t\t\tdata.displacementScale = this.displacementScale;\n\t\t\t\tdata.displacementBias = this.displacementBias;\n\n\t\t\t}\n\t\t\tif ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;\n\t\t\tif ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;\n\t\t\tif ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;\n\n\t\t\tif ( this.envMap && this.envMap.isTexture ) {\n\n\t\t\t\tdata.envMap = this.envMap.toJSON( meta ).uuid;\n\t\t\t\tdata.reflectivity = this.reflectivity; // Scale behind envMap\n\n\t\t\t}\n\n\t\t\tif ( this.gradientMap && this.gradientMap.isTexture ) {\n\n\t\t\t\tdata.gradientMap = this.gradientMap.toJSON( meta ).uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.size !== undefined ) data.size = this.size;\n\t\t\tif ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;\n\n\t\t\tif ( this.blending !== NormalBlending ) data.blending = this.blending;\n\t\t\tif ( this.shading !== SmoothShading ) data.shading = this.shading;\n\t\t\tif ( this.side !== FrontSide ) data.side = this.side;\n\t\t\tif ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;\n\n\t\t\tif ( this.opacity < 1 ) data.opacity = this.opacity;\n\t\t\tif ( this.transparent === true ) data.transparent = this.transparent;\n\n\t\t\tdata.depthFunc = this.depthFunc;\n\t\t\tdata.depthTest = this.depthTest;\n\t\t\tdata.depthWrite = this.depthWrite;\n\n\t\t\tif ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;\n\t\t\tif ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;\n\t\t\tif ( this.wireframe === true ) data.wireframe = this.wireframe;\n\t\t\tif ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;\n\t\t\tif ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;\n\t\t\tif ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;\n\n\t\t\tdata.skinning = this.skinning;\n\t\t\tdata.morphTargets = this.morphTargets;\n\n\t\t\t// TODO: Copied from Object3D.toJSON\n\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t\tif ( isRoot ) {\n\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( textures.length > 0 ) data.textures = textures;\n\t\t\t\tif ( images.length > 0 ) data.images = images;\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.fog = source.fog;\n\t\t\tthis.lights = source.lights;\n\n\t\t\tthis.blending = source.blending;\n\t\t\tthis.side = source.side;\n\t\t\tthis.shading = source.shading;\n\t\t\tthis.vertexColors = source.vertexColors;\n\n\t\t\tthis.opacity = source.opacity;\n\t\t\tthis.transparent = source.transparent;\n\n\t\t\tthis.blendSrc = source.blendSrc;\n\t\t\tthis.blendDst = source.blendDst;\n\t\t\tthis.blendEquation = source.blendEquation;\n\t\t\tthis.blendSrcAlpha = source.blendSrcAlpha;\n\t\t\tthis.blendDstAlpha = source.blendDstAlpha;\n\t\t\tthis.blendEquationAlpha = source.blendEquationAlpha;\n\n\t\t\tthis.depthFunc = source.depthFunc;\n\t\t\tthis.depthTest = source.depthTest;\n\t\t\tthis.depthWrite = source.depthWrite;\n\n\t\t\tthis.colorWrite = source.colorWrite;\n\n\t\t\tthis.precision = source.precision;\n\n\t\t\tthis.polygonOffset = source.polygonOffset;\n\t\t\tthis.polygonOffsetFactor = source.polygonOffsetFactor;\n\t\t\tthis.polygonOffsetUnits = source.polygonOffsetUnits;\n\n\t\t\tthis.alphaTest = source.alphaTest;\n\n\t\t\tthis.premultipliedAlpha = source.premultipliedAlpha;\n\n\t\t\tthis.overdraw = source.overdraw;\n\n\t\t\tthis.visible = source.visible;\n\t\t\tthis.clipShadows = source.clipShadows;\n\t\t\tthis.clipIntersection = source.clipIntersection;\n\n\t\t\tvar srcPlanes = source.clippingPlanes,\n\t\t\t\tdstPlanes = null;\n\n\t\t\tif ( srcPlanes !== null ) {\n\n\t\t\t\tvar n = srcPlanes.length;\n\t\t\t\tdstPlanes = new Array( n );\n\n\t\t\t\tfor ( var i = 0; i !== n; ++ i )\n\t\t\t\t\tdstPlanes[ i ] = srcPlanes[ i ].clone();\n\n\t\t\t}\n\n\t\t\tthis.clippingPlanes = dstPlanes;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdate: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'update' } );\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Material.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * defines: { \"label\" : \"value\" },\n\t * uniforms: { \"parameter1\": { value: 1.0 }, \"parameter2\": { value2: 2 } },\n\t *\n\t * fragmentShader: ,\n\t * vertexShader: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * lights: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction ShaderMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'ShaderMaterial';\n\n\t\tthis.defines = {};\n\t\tthis.uniforms = {};\n\n\t\tthis.vertexShader = 'void main() {\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}';\n\t\tthis.fragmentShader = 'void main() {\\n\\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\\n}';\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false; // set to use scene fog\n\t\tthis.lights = false; // set to use scene lights\n\t\tthis.clipping = false; // set to use user-defined clipping planes\n\n\t\tthis.skinning = false; // set to use skinning attribute streams\n\t\tthis.morphTargets = false; // set to use morph targets\n\t\tthis.morphNormals = false; // set to use morph normals\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false, // set to use derivatives\n\t\t\tfragDepth: false, // set to use fragment depth values\n\t\t\tdrawBuffers: false, // set to use draw buffers\n\t\t\tshaderTextureLOD: false // set to use shader texture LOD\n\t\t};\n\n\t\t// When rendered geometry doesn't include these attributes but the material does,\n\t\t// use these default values in WebGL. This avoids errors when buffer data is missing.\n\t\tthis.defaultAttributeValues = {\n\t\t\t'color': [ 1, 1, 1 ],\n\t\t\t'uv': [ 0, 0 ],\n\t\t\t'uv2': [ 0, 0 ]\n\t\t};\n\n\t\tthis.index0AttributeName = undefined;\n\n\t\tif ( parameters !== undefined ) {\n\n\t\t\tif ( parameters.attributes !== undefined ) {\n\n\t\t\t\tconsole.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );\n\n\t\t\t}\n\n\t\t\tthis.setValues( parameters );\n\n\t\t}\n\n\t}\n\n\tShaderMaterial.prototype = Object.create( Material.prototype );\n\tShaderMaterial.prototype.constructor = ShaderMaterial;\n\n\tShaderMaterial.prototype.isShaderMaterial = true;\n\n\tShaderMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.fragmentShader = source.fragmentShader;\n\t\tthis.vertexShader = source.vertexShader;\n\n\t\tthis.uniforms = UniformsUtils.clone( source.uniforms );\n\n\t\tthis.defines = source.defines;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.lights = source.lights;\n\t\tthis.clipping = source.clipping;\n\n\t\tthis.skinning = source.skinning;\n\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\tthis.extensions = source.extensions;\n\n\t\treturn this;\n\n\t};\n\n\tShaderMaterial.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Material.prototype.toJSON.call( this, meta );\n\n\t\tdata.uniforms = this.uniforms;\n\t\tdata.vertexShader = this.vertexShader;\n\t\tdata.fragmentShader = this.fragmentShader;\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / https://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t *\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t * }\n\t */\n\n\tfunction MeshDepthMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshDepthMaterial';\n\n\t\tthis.depthPacking = BasicDepthPacking;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.map = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshDepthMaterial.prototype = Object.create( Material.prototype );\n\tMeshDepthMaterial.prototype.constructor = MeshDepthMaterial;\n\n\tMeshDepthMaterial.prototype.isMeshDepthMaterial = true;\n\n\tMeshDepthMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.depthPacking = source.depthPacking;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\tthis.map = source.map;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction Box3( min, max ) {\n\n\t\tthis.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );\n\t\tthis.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );\n\n\t}\n\n\tBox3.prototype = {\n\n\t\tconstructor: Box3,\n\n\t\tisBox3: true,\n\n\t\tset: function ( min, max ) {\n\n\t\t\tthis.min.copy( min );\n\t\t\tthis.max.copy( max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromArray: function ( array ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\tvar x = array[ i ];\n\t\t\t\tvar y = array[ i + 1 ];\n\t\t\t\tvar z = array[ i + 2 ];\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromBufferAttribute: function ( attribute ) {\n\n\t\t\tvar minX = + Infinity;\n\t\t\tvar minY = + Infinity;\n\t\t\tvar minZ = + Infinity;\n\n\t\t\tvar maxX = - Infinity;\n\t\t\tvar maxY = - Infinity;\n\t\t\tvar maxZ = - Infinity;\n\n\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\tvar x = attribute.getX( i );\n\t\t\t\tvar y = attribute.getY( i );\n\t\t\t\tvar z = attribute.getZ( i );\n\n\t\t\t\tif ( x < minX ) minX = x;\n\t\t\t\tif ( y < minY ) minY = y;\n\t\t\t\tif ( z < minZ ) minZ = z;\n\n\t\t\t\tif ( x > maxX ) maxX = x;\n\t\t\t\tif ( y > maxY ) maxY = y;\n\t\t\t\tif ( z > maxZ ) maxZ = z;\n\n\t\t\t}\n\n\t\t\tthis.min.set( minX, minY, minZ );\n\t\t\tthis.max.set( maxX, maxY, maxZ );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function ( points ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\tthis.expandByPoint( points[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCenterAndSize: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function setFromCenterAndSize( center, size ) {\n\n\t\t\t\tvar halfSize = v1.copy( size ).multiplyScalar( 0.5 );\n\n\t\t\t\tthis.min.copy( center ).sub( halfSize );\n\t\t\t\tthis.max.copy( center ).add( halfSize );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\tthis.makeEmpty();\n\n\t\t\treturn this.expandByObject( object );\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( box ) {\n\n\t\t\tthis.min.copy( box.min );\n\t\t\tthis.max.copy( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tmakeEmpty: function () {\n\n\t\t\tthis.min.x = this.min.y = this.min.z = + Infinity;\n\t\t\tthis.max.x = this.max.y = this.max.z = - Infinity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tisEmpty: function () {\n\n\t\t\t// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes\n\n\t\t\treturn ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.addVectors( this.min, this.max ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tgetSize: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn this.isEmpty() ? result.set( 0, 0, 0 ) : result.subVectors( this.max, this.min );\n\n\t\t},\n\n\t\texpandByPoint: function ( point ) {\n\n\t\t\tthis.min.min( point );\n\t\t\tthis.max.max( point );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByVector: function ( vector ) {\n\n\t\t\tthis.min.sub( vector );\n\t\t\tthis.max.add( vector );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByScalar: function ( scalar ) {\n\n\t\t\tthis.min.addScalar( - scalar );\n\t\t\tthis.max.addScalar( scalar );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\texpandByObject: function () {\n\n\t\t\t// Computes the world-axis-aligned bounding box of an object (including its children),\n\t\t\t// accounting for both the object's, and children's, world transforms\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function expandByObject( object ) {\n\n\t\t\t\tvar scope = this;\n\n\t\t\t\tobject.updateMatrixWorld( true );\n\n\t\t\t\tobject.traverse( function ( node ) {\n\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tvar geometry = node.geometry;\n\n\t\t\t\t\tif ( geometry !== undefined ) {\n\n\t\t\t\t\t\tif ( geometry.isGeometry ) {\n\n\t\t\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\t\t\tfor ( i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\tv1.copy( vertices[ i ] );\n\t\t\t\t\t\t\t\tv1.applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else if ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\t\tvar attribute = geometry.attributes.position;\n\n\t\t\t\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\t\t\t\tfor ( i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tv1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld );\n\n\t\t\t\t\t\t\t\t\tscope.expandByPoint( v1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn point.x < this.min.x || point.x > this.max.x ||\n\t\t\t\tpoint.y < this.min.y || point.y > this.max.y ||\n\t\t\t\tpoint.z < this.min.z || point.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tcontainsBox: function ( box ) {\n\n\t\t\treturn this.min.x <= box.min.x && box.max.x <= this.max.x &&\n\t\t\t\tthis.min.y <= box.min.y && box.max.y <= this.max.y &&\n\t\t\t\tthis.min.z <= box.min.z && box.max.z <= this.max.z;\n\n\t\t},\n\n\t\tgetParameter: function ( point, optionalTarget ) {\n\n\t\t\t// This can potentially have a divide by zero if the box\n\t\t\t// has a size dimension of 0.\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.set(\n\t\t\t\t( point.x - this.min.x ) / ( this.max.x - this.min.x ),\n\t\t\t\t( point.y - this.min.y ) / ( this.max.y - this.min.y ),\n\t\t\t\t( point.z - this.min.z ) / ( this.max.z - this.min.z )\n\t\t\t);\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\t// using 6 splitting planes to rule out intersections.\n\t\t\treturn box.max.x < this.min.x || box.min.x > this.max.x ||\n\t\t\t\tbox.max.y < this.min.y || box.min.y > this.max.y ||\n\t\t\t\tbox.max.z < this.min.z || box.min.z > this.max.z ? false : true;\n\n\t\t},\n\n\t\tintersectsSphere: ( function () {\n\n\t\t\tvar closestPoint;\n\n\t\t\treturn function intersectsSphere( sphere ) {\n\n\t\t\t\tif ( closestPoint === undefined ) closestPoint = new Vector3();\n\n\t\t\t\t// Find the point on the AABB closest to the sphere center.\n\t\t\t\tthis.clampPoint( sphere.center, closestPoint );\n\n\t\t\t\t// If that point is inside the sphere, the AABB and sphere intersect.\n\t\t\t\treturn closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We compute the minimum and maximum dot product values. If those values\n\t\t\t// are on the same side (back or front) of the plane, then there is no intersection.\n\n\t\t\tvar min, max;\n\n\t\t\tif ( plane.normal.x > 0 ) {\n\n\t\t\t\tmin = plane.normal.x * this.min.x;\n\t\t\t\tmax = plane.normal.x * this.max.x;\n\n\t\t\t} else {\n\n\t\t\t\tmin = plane.normal.x * this.max.x;\n\t\t\t\tmax = plane.normal.x * this.min.x;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.y > 0 ) {\n\n\t\t\t\tmin += plane.normal.y * this.min.y;\n\t\t\t\tmax += plane.normal.y * this.max.y;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.y * this.max.y;\n\t\t\t\tmax += plane.normal.y * this.min.y;\n\n\t\t\t}\n\n\t\t\tif ( plane.normal.z > 0 ) {\n\n\t\t\t\tmin += plane.normal.z * this.min.z;\n\t\t\t\tmax += plane.normal.z * this.max.z;\n\n\t\t\t} else {\n\n\t\t\t\tmin += plane.normal.z * this.max.z;\n\t\t\t\tmax += plane.normal.z * this.min.z;\n\n\t\t\t}\n\n\t\t\treturn ( min <= plane.constant && max >= plane.constant );\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( point ).clamp( this.min, this.max );\n\n\t\t},\n\n\t\tdistanceToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceToPoint( point ) {\n\n\t\t\t\tvar clampedPoint = v1.copy( point ).clamp( this.min, this.max );\n\t\t\t\treturn clampedPoint.sub( point ).length();\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetBoundingSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function getBoundingSphere( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Sphere();\n\n\t\t\t\tthis.getCenter( result.center );\n\n\t\t\t\tresult.radius = this.getSize( v1 ).length() * 0.5;\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersect: function ( box ) {\n\n\t\t\tthis.min.max( box.min );\n\t\t\tthis.max.min( box.max );\n\n\t\t\t// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.\n\t\t\tif( this.isEmpty() ) this.makeEmpty();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tunion: function ( box ) {\n\n\t\t\tthis.min.min( box.min );\n\t\t\tthis.max.max( box.max );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar points = [\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3(),\n\t\t\t\tnew Vector3()\n\t\t\t];\n\n\t\t\treturn function applyMatrix4( matrix ) {\n\n\t\t\t\t// transform of empty box is an empty box.\n\t\t\t\tif( this.isEmpty() ) return this;\n\n\t\t\t\t// NOTE: I am using a binary pattern to specify all 2^3 combinations below\n\t\t\t\tpoints[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000\n\t\t\t\tpoints[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001\n\t\t\t\tpoints[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010\n\t\t\t\tpoints[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011\n\t\t\t\tpoints[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100\n\t\t\t\tpoints[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101\n\t\t\t\tpoints[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110\n\t\t\t\tpoints[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix );\t// 111\n\n\t\t\t\tthis.setFromPoints( points );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.min.add( offset );\n\t\t\tthis.max.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( box ) {\n\n\t\t\treturn box.min.equals( this.min ) && box.max.equals( this.max );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Sphere( center, radius ) {\n\n\t\tthis.center = ( center !== undefined ) ? center : new Vector3();\n\t\tthis.radius = ( radius !== undefined ) ? radius : 0;\n\n\t}\n\n\tSphere.prototype = {\n\n\t\tconstructor: Sphere,\n\n\t\tset: function ( center, radius ) {\n\n\t\t\tthis.center.copy( center );\n\t\t\tthis.radius = radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPoints: function () {\n\n\t\t\tvar box;\n\n\t\t\treturn function setFromPoints( points, optionalCenter ) {\n\n\t\t\t\tif ( box === undefined ) box = new Box3(); // see #10547\n\n\t\t\t\tvar center = this.center;\n\n\t\t\t\tif ( optionalCenter !== undefined ) {\n\n\t\t\t\t\tcenter.copy( optionalCenter );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.setFromPoints( points ).getCenter( center );\n\n\t\t\t\t}\n\n\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\tfor ( var i = 0, il = points.length; i < il; i ++ ) {\n\n\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( sphere ) {\n\n\t\t\tthis.center.copy( sphere.center );\n\t\t\tthis.radius = sphere.radius;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tempty: function () {\n\n\t\t\treturn ( this.radius <= 0 );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn ( point.distanceTo( this.center ) - this.radius );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar radiusSum = this.radius + sphere.radius;\n\n\t\t\treturn sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsSphere( this );\n\n\t\t},\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// We use the following equation to compute the signed distance from\n\t\t\t// the center of the sphere to the plane.\n\t\t\t//\n\t\t\t// distance = q * n - d\n\t\t\t//\n\t\t\t// If this distance is greater than the radius of the sphere,\n\t\t\t// then there is no intersection.\n\n\t\t\treturn Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;\n\n\t\t},\n\n\t\tclampPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar deltaLengthSq = this.center.distanceToSquared( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.copy( point );\n\n\t\t\tif ( deltaLengthSq > ( this.radius * this.radius ) ) {\n\n\t\t\t\tresult.sub( this.center ).normalize();\n\t\t\t\tresult.multiplyScalar( this.radius ).add( this.center );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\tgetBoundingBox: function ( optionalTarget ) {\n\n\t\t\tvar box = optionalTarget || new Box3();\n\n\t\t\tbox.set( this.center, this.center );\n\t\t\tbox.expandByScalar( this.radius );\n\n\t\t\treturn box;\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.center.applyMatrix4( matrix );\n\t\t\tthis.radius = this.radius * matrix.getMaxScaleOnAxis();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.center.add( offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( sphere ) {\n\n\t\t\treturn sphere.center.equals( this.center ) && ( sphere.radius === this.radius );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t * @author tschw\n\t */\n\n\tfunction Matrix3() {\n\n\t\tthis.elements = new Float32Array( [\n\n\t\t\t1, 0, 0,\n\t\t\t0, 1, 0,\n\t\t\t0, 0, 1\n\n\t\t] );\n\n\t\tif ( arguments.length > 0 ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );\n\n\t\t}\n\n\t}\n\n\tMatrix3.prototype = {\n\n\t\tconstructor: Matrix3,\n\n\t\tisMatrix3: true,\n\n\t\tset: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;\n\t\t\tte[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;\n\t\t\tte[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tidentity: function () {\n\n\t\t\tthis.set(\n\n\t\t\t\t1, 0, 0,\n\t\t\t\t0, 1, 0,\n\t\t\t\t0, 0, 1\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().fromArray( this.elements );\n\n\t\t},\n\n\t\tcopy: function ( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 3 ], me[ 6 ],\n\t\t\t\tme[ 1 ], me[ 4 ], me[ 7 ],\n\t\t\t\tme[ 2 ], me[ 5 ], me[ 8 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix4: function( m ) {\n\n\t\t\tvar me = m.elements;\n\n\t\t\tthis.set(\n\n\t\t\t\tme[ 0 ], me[ 4 ], me[ 8 ],\n\t\t\t\tme[ 1 ], me[ 5 ], me[ 9 ],\n\t\t\t\tme[ 2 ], me[ 6 ], me[ 10 ]\n\n\t\t\t);\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tapplyToBufferAttribute: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function applyToBufferAttribute( attribute ) {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\n\t\t\t\tfor ( var i = 0, l = attribute.count; i < l; i ++ ) {\n\n\t\t\t\t\tv1.x = attribute.getX( i );\n\t\t\t\t\tv1.y = attribute.getY( i );\n\t\t\t\t\tv1.z = attribute.getZ( i );\n\n\t\t\t\t\tv1.applyMatrix3( this );\n\n\t\t\t\t\tattribute.setXYZ( i, v1.x, v1.y, v1.z );\n\n\t\t\t\t}\n\n\t\t\t\treturn attribute;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmultiplyScalar: function ( s ) {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tte[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;\n\t\t\tte[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;\n\t\t\tte[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdeterminant: function () {\n\n\t\t\tvar te = this.elements;\n\n\t\t\tvar a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],\n\t\t\t\td = te[ 3 ], e = te[ 4 ], f = te[ 5 ],\n\t\t\t\tg = te[ 6 ], h = te[ 7 ], i = te[ 8 ];\n\n\t\t\treturn a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;\n\n\t\t},\n\n\t\tgetInverse: function ( matrix, throwOnDegenerate ) {\n\n\t\t\tif ( matrix && matrix.isMatrix4 ) {\n\n\t\t\t\tconsole.error( \"THREE.Matrix3.getInverse no longer takes a Matrix4 argument.\" );\n\n\t\t\t}\n\n\t\t\tvar me = matrix.elements,\n\t\t\t\tte = this.elements,\n\n\t\t\t\tn11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],\n\t\t\t\tn12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],\n\t\t\t\tn13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],\n\n\t\t\t\tt11 = n33 * n22 - n32 * n23,\n\t\t\t\tt12 = n32 * n13 - n33 * n12,\n\t\t\t\tt13 = n23 * n12 - n22 * n13,\n\n\t\t\t\tdet = n11 * t11 + n21 * t12 + n31 * t13;\n\n\t\t\tif ( det === 0 ) {\n\n\t\t\t\tvar msg = \"THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0\";\n\n\t\t\t\tif ( throwOnDegenerate === true ) {\n\n\t\t\t\t\tthrow new Error( msg );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( msg );\n\n\t\t\t\t}\n\n\t\t\t\treturn this.identity();\n\t\t\t}\n\n\t\t\tvar detInv = 1 / det;\n\n\t\t\tte[ 0 ] = t11 * detInv;\n\t\t\tte[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;\n\t\t\tte[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;\n\n\t\t\tte[ 3 ] = t12 * detInv;\n\t\t\tte[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;\n\t\t\tte[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;\n\n\t\t\tte[ 6 ] = t13 * detInv;\n\t\t\tte[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;\n\t\t\tte[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttranspose: function () {\n\n\t\t\tvar tmp, m = this.elements;\n\n\t\t\ttmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;\n\t\t\ttmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;\n\t\t\ttmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetNormalMatrix: function ( matrix4 ) {\n\n\t\t\treturn this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();\n\n\t\t},\n\n\t\ttransposeIntoArray: function ( r ) {\n\n\t\t\tvar m = this.elements;\n\n\t\t\tr[ 0 ] = m[ 0 ];\n\t\t\tr[ 1 ] = m[ 3 ];\n\t\t\tr[ 2 ] = m[ 6 ];\n\t\t\tr[ 3 ] = m[ 1 ];\n\t\t\tr[ 4 ] = m[ 4 ];\n\t\t\tr[ 5 ] = m[ 7 ];\n\t\t\tr[ 6 ] = m[ 2 ];\n\t\t\tr[ 7 ] = m[ 5 ];\n\t\t\tr[ 8 ] = m[ 8 ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromArray: function ( array, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tfor( var i = 0; i < 9; i ++ ) {\n\n\t\t\t\tthis.elements[ i ] = array[ i + offset ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar te = this.elements;\n\n\t\t\tarray[ offset ] = te[ 0 ];\n\t\t\tarray[ offset + 1 ] = te[ 1 ];\n\t\t\tarray[ offset + 2 ] = te[ 2 ];\n\n\t\t\tarray[ offset + 3 ] = te[ 3 ];\n\t\t\tarray[ offset + 4 ] = te[ 4 ];\n\t\t\tarray[ offset + 5 ] = te[ 5 ];\n\n\t\t\tarray[ offset + 6 ] = te[ 6 ];\n\t\t\tarray[ offset + 7 ] = te[ 7 ];\n\t\t\tarray[ offset + 8 ] = te[ 8 ];\n\n\t\t\treturn array;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Plane( normal, constant ) {\n\n\t\tthis.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );\n\t\tthis.constant = ( constant !== undefined ) ? constant : 0;\n\n\t}\n\n\tPlane.prototype = {\n\n\t\tconstructor: Plane,\n\n\t\tset: function ( normal, constant ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetComponents: function ( x, y, z, w ) {\n\n\t\t\tthis.normal.set( x, y, z );\n\t\t\tthis.constant = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromNormalAndCoplanarPoint: function ( normal, point ) {\n\n\t\t\tthis.normal.copy( normal );\n\t\t\tthis.constant = - point.dot( this.normal );\t// must be this.normal, not normal, as this.normal is normalized\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromCoplanarPoints: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function setFromCoplanarPoints( a, b, c ) {\n\n\t\t\t\tvar normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();\n\n\t\t\t\t// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?\n\n\t\t\t\tthis.setFromNormalAndCoplanarPoint( normal, a );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( plane ) {\n\n\t\t\tthis.normal.copy( plane.normal );\n\t\t\tthis.constant = plane.constant;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\t// Note: will lead to a divide by zero if the plane is invalid.\n\n\t\t\tvar inverseNormalLength = 1.0 / this.normal.length();\n\t\t\tthis.normal.multiplyScalar( inverseNormalLength );\n\t\t\tthis.constant *= inverseNormalLength;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnegate: function () {\n\n\t\t\tthis.constant *= - 1;\n\t\t\tthis.normal.negate();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn this.normal.dot( point ) + this.constant;\n\n\t\t},\n\n\t\tdistanceToSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) - sphere.radius;\n\n\t\t},\n\n\t\tprojectPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn this.orthoPoint( point, optionalTarget ).sub( point ).negate();\n\n\t\t},\n\n\t\torthoPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar perpendicularMagnitude = this.distanceToPoint( point );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );\n\n\t\t},\n\n\t\tintersectLine: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectLine( line, optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tvar direction = line.delta( v1 );\n\n\t\t\t\tvar denominator = this.normal.dot( direction );\n\n\t\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t\t// line is coplanar, return origin\n\t\t\t\t\tif ( this.distanceToPoint( line.start ) === 0 ) {\n\n\t\t\t\t\t\treturn result.copy( line.start );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Unsure if this is the correct method to handle this case.\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\tvar t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;\n\n\t\t\t\tif ( t < 0 || t > 1 ) {\n\n\t\t\t\t\treturn undefined;\n\n\t\t\t\t}\n\n\t\t\t\treturn result.copy( direction ).multiplyScalar( t ).add( line.start );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsLine: function ( line ) {\n\n\t\t\t// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.\n\n\t\t\tvar startSign = this.distanceToPoint( line.start );\n\t\t\tvar endSign = this.distanceToPoint( line.end );\n\n\t\t\treturn ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );\n\n\t\t},\n\n\t\tintersectsBox: function ( box ) {\n\n\t\t\treturn box.intersectsPlane( this );\n\n\t\t},\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn sphere.intersectsPlane( this );\n\n\t\t},\n\n\t\tcoplanarPoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.copy( this.normal ).multiplyScalar( - this.constant );\n\n\t\t},\n\n\t\tapplyMatrix4: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar m1 = new Matrix3();\n\n\t\t\treturn function applyMatrix4( matrix, optionalNormalMatrix ) {\n\n\t\t\t\tvar referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );\n\n\t\t\t\t// transform normal based on theory here:\n\t\t\t\t// http://www.songho.ca/opengl/gl_normaltransform.html\n\t\t\t\tvar normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );\n\t\t\t\tvar normal = this.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t// recalculate constant (like in setFromNormalAndCoplanarPoint)\n\t\t\t\tthis.constant = - referencePoint.dot( normal );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function ( offset ) {\n\n\t\t\tthis.constant = this.constant - offset.dot( this.normal );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( plane ) {\n\n\t\t\treturn plane.normal.equals( this.normal ) && ( plane.constant === this.constant );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Frustum( p0, p1, p2, p3, p4, p5 ) {\n\n\t\tthis.planes = [\n\n\t\t\t( p0 !== undefined ) ? p0 : new Plane(),\n\t\t\t( p1 !== undefined ) ? p1 : new Plane(),\n\t\t\t( p2 !== undefined ) ? p2 : new Plane(),\n\t\t\t( p3 !== undefined ) ? p3 : new Plane(),\n\t\t\t( p4 !== undefined ) ? p4 : new Plane(),\n\t\t\t( p5 !== undefined ) ? p5 : new Plane()\n\n\t\t];\n\n\t}\n\n\tFrustum.prototype = {\n\n\t\tconstructor: Frustum,\n\n\t\tset: function ( p0, p1, p2, p3, p4, p5 ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tplanes[ 0 ].copy( p0 );\n\t\t\tplanes[ 1 ].copy( p1 );\n\t\t\tplanes[ 2 ].copy( p2 );\n\t\t\tplanes[ 3 ].copy( p3 );\n\t\t\tplanes[ 4 ].copy( p4 );\n\t\t\tplanes[ 5 ].copy( p5 );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( frustum ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tplanes[ i ].copy( frustum.planes[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromMatrix: function ( m ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar me = m.elements;\n\t\t\tvar me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];\n\t\t\tvar me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];\n\t\t\tvar me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];\n\t\t\tvar me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];\n\n\t\t\tplanes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();\n\t\t\tplanes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();\n\t\t\tplanes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();\n\t\t\tplanes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();\n\t\t\tplanes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();\n\t\t\tplanes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tintersectsObject: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsObject( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere )\n\t\t\t\t\t.applyMatrix4( object.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSprite: function () {\n\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function intersectsSprite( sprite ) {\n\n\t\t\t\tsphere.center.set( 0, 0, 0 );\n\t\t\t\tsphere.radius = 0.7071067811865476;\n\t\t\t\tsphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\tvar planes = this.planes;\n\t\t\tvar center = sphere.center;\n\t\t\tvar negRadius = - sphere.radius;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tvar distance = planes[ i ].distanceToPoint( center );\n\n\t\t\t\tif ( distance < negRadius ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t},\n\n\t\tintersectsBox: function () {\n\n\t\t\tvar p1 = new Vector3(),\n\t\t\t\tp2 = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\tvar planes = this.planes;\n\n\t\t\t\tfor ( var i = 0; i < 6 ; i ++ ) {\n\n\t\t\t\t\tvar plane = planes[ i ];\n\n\t\t\t\t\tp1.x = plane.normal.x > 0 ? box.min.x : box.max.x;\n\t\t\t\t\tp2.x = plane.normal.x > 0 ? box.max.x : box.min.x;\n\t\t\t\t\tp1.y = plane.normal.y > 0 ? box.min.y : box.max.y;\n\t\t\t\t\tp2.y = plane.normal.y > 0 ? box.max.y : box.min.y;\n\t\t\t\t\tp1.z = plane.normal.z > 0 ? box.min.z : box.max.z;\n\t\t\t\t\tp2.z = plane.normal.z > 0 ? box.max.z : box.min.z;\n\n\t\t\t\t\tvar d1 = plane.distanceToPoint( p1 );\n\t\t\t\t\tvar d2 = plane.distanceToPoint( p2 );\n\n\t\t\t\t\t// if both outside plane, no intersection\n\n\t\t\t\t\tif ( d1 < 0 && d2 < 0 ) {\n\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t};\n\n\t\t}(),\n\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\tvar planes = this.planes;\n\n\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\tif ( planes[ i ].distanceToPoint( point ) < 0 ) {\n\n\t\t\t\t\treturn false;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {\n\n\t\tvar _gl = _renderer.context,\n\t\t_state = _renderer.state,\n\t\t_frustum = new Frustum(),\n\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t_lightShadows = _lights.shadows,\n\n\t\t_shadowMapSize = new Vector2(),\n\t\t_maxShadowMapSize = new Vector2( capabilities.maxTextureSize, capabilities.maxTextureSize ),\n\n\t\t_lookTarget = new Vector3(),\n\t\t_lightPositionWorld = new Vector3(),\n\n\t\t_renderList = [],\n\n\t\t_MorphingFlag = 1,\n\t\t_SkinningFlag = 2,\n\n\t\t_NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1,\n\n\t\t_depthMaterials = new Array( _NumberOfMaterialVariants ),\n\t\t_distanceMaterials = new Array( _NumberOfMaterialVariants ),\n\n\t\t_materialCache = {};\n\n\t\tvar cubeDirections = [\n\t\t\tnew Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),\n\t\t\tnew Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )\n\t\t];\n\n\t\tvar cubeUps = [\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),\n\t\t\tnew Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),\tnew Vector3( 0, 0, - 1 )\n\t\t];\n\n\t\tvar cube2DViewPorts = [\n\t\t\tnew Vector4(), new Vector4(), new Vector4(),\n\t\t\tnew Vector4(), new Vector4(), new Vector4()\n\t\t];\n\n\t\t// init\n\n\t\tvar depthMaterialTemplate = new MeshDepthMaterial();\n\t\tdepthMaterialTemplate.depthPacking = RGBADepthPacking;\n\t\tdepthMaterialTemplate.clipping = true;\n\n\t\tvar distanceShader = ShaderLib[ \"distanceRGBA\" ];\n\t\tvar distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );\n\n\t\tfor ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {\n\n\t\t\tvar useMorphing = ( i & _MorphingFlag ) !== 0;\n\t\t\tvar useSkinning = ( i & _SkinningFlag ) !== 0;\n\n\t\t\tvar depthMaterial = depthMaterialTemplate.clone();\n\t\t\tdepthMaterial.morphTargets = useMorphing;\n\t\t\tdepthMaterial.skinning = useSkinning;\n\n\t\t\t_depthMaterials[ i ] = depthMaterial;\n\n\t\t\tvar distanceMaterial = new ShaderMaterial( {\n\t\t\t\tdefines: {\n\t\t\t\t\t'USE_SHADOWMAP': ''\n\t\t\t\t},\n\t\t\t\tuniforms: distanceUniforms,\n\t\t\t\tvertexShader: distanceShader.vertexShader,\n\t\t\t\tfragmentShader: distanceShader.fragmentShader,\n\t\t\t\tmorphTargets: useMorphing,\n\t\t\t\tskinning: useSkinning,\n\t\t\t\tclipping: true\n\t\t\t} );\n\n\t\t\t_distanceMaterials[ i ] = distanceMaterial;\n\n\t\t}\n\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tthis.enabled = false;\n\n\t\tthis.autoUpdate = true;\n\t\tthis.needsUpdate = false;\n\n\t\tthis.type = PCFShadowMap;\n\n\t\tthis.renderReverseSided = true;\n\t\tthis.renderSingleSided = true;\n\n\t\tthis.render = function ( scene, camera ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\t\t\tif ( scope.autoUpdate === false && scope.needsUpdate === false ) return;\n\n\t\t\tif ( _lightShadows.length === 0 ) return;\n\n\t\t\t// Set GL state for depth map.\n\t\t\t_state.buffers.color.setClear( 1, 1, 1, 1 );\n\t\t\t_state.disable( _gl.BLEND );\n\t\t\t_state.setDepthTest( true );\n\t\t\t_state.setScissorTest( false );\n\n\t\t\t// render depth map\n\n\t\t\tvar faceCount, isPointLight;\n\n\t\t\tfor ( var i = 0, il = _lightShadows.length; i < il; i ++ ) {\n\n\t\t\t\tvar light = _lightShadows[ i ];\n\t\t\t\tvar shadow = light.shadow;\n\n\t\t\t\tif ( shadow === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowCamera = shadow.camera;\n\n\t\t\t\t_shadowMapSize.copy( shadow.mapSize );\n\t\t\t\t_shadowMapSize.min( _maxShadowMapSize );\n\n\t\t\t\tif ( light && light.isPointLight ) {\n\n\t\t\t\t\tfaceCount = 6;\n\t\t\t\t\tisPointLight = true;\n\n\t\t\t\t\tvar vpWidth = _shadowMapSize.x;\n\t\t\t\t\tvar vpHeight = _shadowMapSize.y;\n\n\t\t\t\t\t// These viewports map a cube-map onto a 2D texture with the\n\t\t\t\t\t// following orientation:\n\t\t\t\t\t//\n\t\t\t\t\t// xzXZ\n\t\t\t\t\t// y Y\n\t\t\t\t\t//\n\t\t\t\t\t// X - Positive x direction\n\t\t\t\t\t// x - Negative x direction\n\t\t\t\t\t// Y - Positive y direction\n\t\t\t\t\t// y - Negative y direction\n\t\t\t\t\t// Z - Positive z direction\n\t\t\t\t\t// z - Negative z direction\n\n\t\t\t\t\t// positive X\n\t\t\t\t\tcube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative X\n\t\t\t\t\tcube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Z\n\t\t\t\t\tcube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// negative Z\n\t\t\t\t\tcube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );\n\t\t\t\t\t// positive Y\n\t\t\t\t\tcube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );\n\t\t\t\t\t// negative Y\n\t\t\t\t\tcube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );\n\n\t\t\t\t\t_shadowMapSize.x *= 4.0;\n\t\t\t\t\t_shadowMapSize.y *= 2.0;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfaceCount = 1;\n\t\t\t\t\tisPointLight = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.map === null ) {\n\n\t\t\t\t\tvar pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };\n\n\t\t\t\t\tshadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );\n\n\t\t\t\t\tshadowCamera.updateProjectionMatrix();\n\n\t\t\t\t}\n\n\t\t\t\tif ( shadow.isSpotLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\t// TODO (abelnation / sam-g-steel): is this needed?\n\t\t\t\tif (shadow && shadow.isRectAreaLightShadow ) {\n\n\t\t\t\t\tshadow.update( light );\n\n\t\t\t\t}\n\n\t\t\t\tvar shadowMap = shadow.map;\n\t\t\t\tvar shadowMatrix = shadow.matrix;\n\n\t\t\t\t_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\tshadowCamera.position.copy( _lightPositionWorld );\n\n\t\t\t\t_renderer.setRenderTarget( shadowMap );\n\t\t\t\t_renderer.clear();\n\n\t\t\t\t// render shadow map for each cube face (if omni-directional) or\n\t\t\t\t// run a single pass if not\n\n\t\t\t\tfor ( var face = 0; face < faceCount; face ++ ) {\n\n\t\t\t\t\tif ( isPointLight ) {\n\n\t\t\t\t\t\t_lookTarget.copy( shadowCamera.position );\n\t\t\t\t\t\t_lookTarget.add( cubeDirections[ face ] );\n\t\t\t\t\t\tshadowCamera.up.copy( cubeUps[ face ] );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t\tvar vpDimensions = cube2DViewPorts[ face ];\n\t\t\t\t\t\t_state.viewport( vpDimensions );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_lookTarget.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\t\tshadowCamera.lookAt( _lookTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tshadowCamera.updateMatrixWorld();\n\t\t\t\t\tshadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );\n\n\t\t\t\t\t// compute shadow matrix\n\n\t\t\t\t\tshadowMatrix.set(\n\t\t\t\t\t\t0.5, 0.0, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.5, 0.0, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.5, 0.5,\n\t\t\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t\t\t);\n\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.projectionMatrix );\n\t\t\t\t\tshadowMatrix.multiply( shadowCamera.matrixWorldInverse );\n\n\t\t\t\t\t// update camera matrices and frustum\n\n\t\t\t\t\t_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );\n\t\t\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\t\t\t// set object matrices & frustum culling\n\n\t\t\t\t\t_renderList.length = 0;\n\n\t\t\t\t\tprojectObject( scene, camera, shadowCamera );\n\n\t\t\t\t\t// render shadow map\n\t\t\t\t\t// render regular objects\n\n\t\t\t\t\tfor ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar object = _renderList[ j ];\n\t\t\t\t\t\tvar geometry = _objects.update( object );\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material && material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\tfor ( var k = 0, kl = groups.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\t\t\tvar group = groups[ k ];\n\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );\n\t\t\t\t\t\t\t_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Restore GL state.\n\t\t\tvar clearColor = _renderer.getClearColor(),\n\t\t\tclearAlpha = _renderer.getClearAlpha();\n\t\t\t_renderer.setClearColor( clearColor, clearAlpha );\n\n\t\t\tscope.needsUpdate = false;\n\n\t\t};\n\n\t\tfunction getDepthMaterial( object, material, isPointLight, lightPositionWorld ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tvar result = null;\n\n\t\t\tvar materialVariants = _depthMaterials;\n\t\t\tvar customMaterial = object.customDepthMaterial;\n\n\t\t\tif ( isPointLight ) {\n\n\t\t\t\tmaterialVariants = _distanceMaterials;\n\t\t\t\tcustomMaterial = object.customDistanceMaterial;\n\n\t\t\t}\n\n\t\t\tif ( ! customMaterial ) {\n\n\t\t\t\tvar useMorphing = false;\n\n\t\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\t\tif ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;\n\n\t\t\t\t\t} else if ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\t\tuseMorphing = geometry.morphTargets && geometry.morphTargets.length > 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar useSkinning = object.isSkinnedMesh && material.skinning;\n\n\t\t\t\tvar variantIndex = 0;\n\n\t\t\t\tif ( useMorphing ) variantIndex |= _MorphingFlag;\n\t\t\t\tif ( useSkinning ) variantIndex |= _SkinningFlag;\n\n\t\t\t\tresult = materialVariants[ variantIndex ];\n\n\t\t\t} else {\n\n\t\t\t\tresult = customMaterial;\n\n\t\t\t}\n\n\t\t\tif ( _renderer.localClippingEnabled &&\n\t\t\t\t material.clipShadows === true &&\n\t\t\t\t\tmaterial.clippingPlanes.length !== 0 ) {\n\n\t\t\t\t// in this case we need a unique material instance reflecting the\n\t\t\t\t// appropriate state\n\n\t\t\t\tvar keyA = result.uuid, keyB = material.uuid;\n\n\t\t\t\tvar materialsForVariant = _materialCache[ keyA ];\n\n\t\t\t\tif ( materialsForVariant === undefined ) {\n\n\t\t\t\t\tmaterialsForVariant = {};\n\t\t\t\t\t_materialCache[ keyA ] = materialsForVariant;\n\n\t\t\t\t}\n\n\t\t\t\tvar cachedMaterial = materialsForVariant[ keyB ];\n\n\t\t\t\tif ( cachedMaterial === undefined ) {\n\n\t\t\t\t\tcachedMaterial = result.clone();\n\t\t\t\t\tmaterialsForVariant[ keyB ] = cachedMaterial;\n\n\t\t\t\t}\n\n\t\t\t\tresult = cachedMaterial;\n\n\t\t\t}\n\n\t\t\tresult.visible = material.visible;\n\t\t\tresult.wireframe = material.wireframe;\n\n\t\t\tvar side = material.side;\n\n\t\t\tif ( scope.renderSingleSided && side == DoubleSide ) {\n\n\t\t\t\tside = FrontSide;\n\n\t\t\t}\n\n\t\t\tif ( scope.renderReverseSided ) {\n\n\t\t\t\tif ( side === FrontSide ) side = BackSide;\n\t\t\t\telse if ( side === BackSide ) side = FrontSide;\n\n\t\t\t}\n\n\t\t\tresult.side = side;\n\n\t\t\tresult.clipShadows = material.clipShadows;\n\t\t\tresult.clippingPlanes = material.clippingPlanes;\n\n\t\t\tresult.wireframeLinewidth = material.wireframeLinewidth;\n\t\t\tresult.linewidth = material.linewidth;\n\n\t\t\tif ( isPointLight && result.uniforms.lightPos !== undefined ) {\n\n\t\t\t\tresult.uniforms.lightPos.value.copy( lightPositionWorld );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera, shadowCamera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {\n\n\t\t\t\tif ( object.castShadow && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {\n\n\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\tobject.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\t\t\t_renderList.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera, shadowCamera );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Ray( origin, direction ) {\n\n\t\tthis.origin = ( origin !== undefined ) ? origin : new Vector3();\n\t\tthis.direction = ( direction !== undefined ) ? direction : new Vector3();\n\n\t}\n\n\tRay.prototype = {\n\n\t\tconstructor: Ray,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\tthis.origin.copy( origin );\n\t\t\tthis.direction.copy( direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( ray ) {\n\n\t\t\tthis.origin.copy( ray.origin );\n\t\t\tthis.direction.copy( ray.direction );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( t ).add( this.origin );\n\n\t\t},\n\n\t\tlookAt: function ( v ) {\n\n\t\t\tthis.direction.copy( v ).sub( this.origin ).normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trecast: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function recast( t ) {\n\n\t\t\t\tthis.origin.copy( this.at( t, v1 ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\tresult.subVectors( point, this.origin );\n\t\t\tvar directionDistance = result.dot( this.direction );\n\n\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\treturn result.copy( this.origin );\n\n\t\t\t}\n\n\t\t\treturn result.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t},\n\n\t\tdistanceToPoint: function ( point ) {\n\n\t\t\treturn Math.sqrt( this.distanceSqToPoint( point ) );\n\n\t\t},\n\n\t\tdistanceSqToPoint: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function distanceSqToPoint( point ) {\n\n\t\t\t\tvar directionDistance = v1.subVectors( point, this.origin ).dot( this.direction );\n\n\t\t\t\t// point behind the ray\n\n\t\t\t\tif ( directionDistance < 0 ) {\n\n\t\t\t\t\treturn this.origin.distanceToSquared( point );\n\n\t\t\t\t}\n\n\t\t\t\tv1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );\n\n\t\t\t\treturn v1.distanceToSquared( point );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tdistanceSqToSegment: function () {\n\n\t\t\tvar segCenter = new Vector3();\n\t\t\tvar segDir = new Vector3();\n\t\t\tvar diff = new Vector3();\n\n\t\t\treturn function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h\n\t\t\t\t// It returns the min distance between the ray and the segment\n\t\t\t\t// defined by v0 and v1\n\t\t\t\t// It can also set two optional targets :\n\t\t\t\t// - The closest point on the ray\n\t\t\t\t// - The closest point on the segment\n\n\t\t\t\tsegCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );\n\t\t\t\tsegDir.copy( v1 ).sub( v0 ).normalize();\n\t\t\t\tdiff.copy( this.origin ).sub( segCenter );\n\n\t\t\t\tvar segExtent = v0.distanceTo( v1 ) * 0.5;\n\t\t\t\tvar a01 = - this.direction.dot( segDir );\n\t\t\t\tvar b0 = diff.dot( this.direction );\n\t\t\t\tvar b1 = - diff.dot( segDir );\n\t\t\t\tvar c = diff.lengthSq();\n\t\t\t\tvar det = Math.abs( 1 - a01 * a01 );\n\t\t\t\tvar s0, s1, sqrDist, extDet;\n\n\t\t\t\tif ( det > 0 ) {\n\n\t\t\t\t\t// The ray and segment are not parallel.\n\n\t\t\t\t\ts0 = a01 * b1 - b0;\n\t\t\t\t\ts1 = a01 * b0 - b1;\n\t\t\t\t\textDet = segExtent * det;\n\n\t\t\t\t\tif ( s0 >= 0 ) {\n\n\t\t\t\t\t\tif ( s1 >= - extDet ) {\n\n\t\t\t\t\t\t\tif ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t\t// region 0\n\t\t\t\t\t\t\t\t// Minimum at interior points of ray and segment.\n\n\t\t\t\t\t\t\t\tvar invDet = 1 / det;\n\t\t\t\t\t\t\t\ts0 *= invDet;\n\t\t\t\t\t\t\t\ts1 *= invDet;\n\t\t\t\t\t\t\t\tsqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// region 1\n\n\t\t\t\t\t\t\t\ts1 = segExtent;\n\t\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 5\n\n\t\t\t\t\t\t\ts1 = - segExtent;\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( s1 <= - extDet ) {\n\n\t\t\t\t\t\t\t// region 4\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else if ( s1 <= extDet ) {\n\n\t\t\t\t\t\t\t// region 3\n\n\t\t\t\t\t\t\ts0 = 0;\n\t\t\t\t\t\t\ts1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// region 2\n\n\t\t\t\t\t\t\ts0 = Math.max( 0, - ( a01 * segExtent + b0 ) );\n\t\t\t\t\t\t\ts1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );\n\t\t\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Ray and segment are parallel.\n\n\t\t\t\t\ts1 = ( a01 > 0 ) ? - segExtent : segExtent;\n\t\t\t\t\ts0 = Math.max( 0, - ( a01 * s1 + b0 ) );\n\t\t\t\t\tsqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnRay ) {\n\n\t\t\t\t\toptionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );\n\n\t\t\t\t}\n\n\t\t\t\tif ( optionalPointOnSegment ) {\n\n\t\t\t\t\toptionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );\n\n\t\t\t\t}\n\n\t\t\t\treturn sqrDist;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectSphere: function () {\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function intersectSphere( sphere, optionalTarget ) {\n\n\t\t\t\tv1.subVectors( sphere.center, this.origin );\n\t\t\t\tvar tca = v1.dot( this.direction );\n\t\t\t\tvar d2 = v1.dot( v1 ) - tca * tca;\n\t\t\t\tvar radius2 = sphere.radius * sphere.radius;\n\n\t\t\t\tif ( d2 > radius2 ) return null;\n\n\t\t\t\tvar thc = Math.sqrt( radius2 - d2 );\n\n\t\t\t\t// t0 = first intersect point - entrance on front of sphere\n\t\t\t\tvar t0 = tca - thc;\n\n\t\t\t\t// t1 = second intersect point - exit point on back of sphere\n\t\t\t\tvar t1 = tca + thc;\n\n\t\t\t\t// test to see if both t0 and t1 are behind the ray - if so, return null\n\t\t\t\tif ( t0 < 0 && t1 < 0 ) return null;\n\n\t\t\t\t// test to see if t0 is behind the ray:\n\t\t\t\t// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,\n\t\t\t\t// in order to always return an intersect point that is in front of the ray.\n\t\t\t\tif ( t0 < 0 ) return this.at( t1, optionalTarget );\n\n\t\t\t\t// else t0 is in front of the ray, so return the first collision point scaled by t0\n\t\t\t\treturn this.at( t0, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tintersectsSphere: function ( sphere ) {\n\n\t\t\treturn this.distanceToPoint( sphere.center ) <= sphere.radius;\n\n\t\t},\n\n\t\tdistanceToPlane: function ( plane ) {\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator === 0 ) {\n\n\t\t\t\t// line is coplanar, return origin\n\t\t\t\tif ( plane.distanceToPoint( this.origin ) === 0 ) {\n\n\t\t\t\t\treturn 0;\n\n\t\t\t\t}\n\n\t\t\t\t// Null is preferable to undefined since undefined means.... it is undefined\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;\n\n\t\t\t// Return if the ray never intersects the plane\n\n\t\t\treturn t >= 0 ? t : null;\n\n\t\t},\n\n\t\tintersectPlane: function ( plane, optionalTarget ) {\n\n\t\t\tvar t = this.distanceToPlane( plane );\n\n\t\t\tif ( t === null ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\treturn this.at( t, optionalTarget );\n\n\t\t},\n\n\n\n\t\tintersectsPlane: function ( plane ) {\n\n\t\t\t// check if the ray lies on the plane first\n\n\t\t\tvar distToPoint = plane.distanceToPoint( this.origin );\n\n\t\t\tif ( distToPoint === 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\tvar denominator = plane.normal.dot( this.direction );\n\n\t\t\tif ( denominator * distToPoint < 0 ) {\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// ray origin is behind the plane (and is pointing behind it)\n\n\t\t\treturn false;\n\n\t\t},\n\n\t\tintersectBox: function ( box, optionalTarget ) {\n\n\t\t\tvar tmin, tmax, tymin, tymax, tzmin, tzmax;\n\n\t\t\tvar invdirx = 1 / this.direction.x,\n\t\t\t\tinvdiry = 1 / this.direction.y,\n\t\t\t\tinvdirz = 1 / this.direction.z;\n\n\t\t\tvar origin = this.origin;\n\n\t\t\tif ( invdirx >= 0 ) {\n\n\t\t\t\ttmin = ( box.min.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.max.x - origin.x ) * invdirx;\n\n\t\t\t} else {\n\n\t\t\t\ttmin = ( box.max.x - origin.x ) * invdirx;\n\t\t\t\ttmax = ( box.min.x - origin.x ) * invdirx;\n\n\t\t\t}\n\n\t\t\tif ( invdiry >= 0 ) {\n\n\t\t\t\ttymin = ( box.min.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.max.y - origin.y ) * invdiry;\n\n\t\t\t} else {\n\n\t\t\t\ttymin = ( box.max.y - origin.y ) * invdiry;\n\t\t\t\ttymax = ( box.min.y - origin.y ) * invdiry;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tymax ) || ( tymin > tmax ) ) return null;\n\n\t\t\t// These lines also handle the case where tmin or tmax is NaN\n\t\t\t// (result of 0 * Infinity). x !== x returns true if x is NaN\n\n\t\t\tif ( tymin > tmin || tmin !== tmin ) tmin = tymin;\n\n\t\t\tif ( tymax < tmax || tmax !== tmax ) tmax = tymax;\n\n\t\t\tif ( invdirz >= 0 ) {\n\n\t\t\t\ttzmin = ( box.min.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.max.z - origin.z ) * invdirz;\n\n\t\t\t} else {\n\n\t\t\t\ttzmin = ( box.max.z - origin.z ) * invdirz;\n\t\t\t\ttzmax = ( box.min.z - origin.z ) * invdirz;\n\n\t\t\t}\n\n\t\t\tif ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null;\n\n\t\t\tif ( tzmin > tmin || tmin !== tmin ) tmin = tzmin;\n\n\t\t\tif ( tzmax < tmax || tmax !== tmax ) tmax = tzmax;\n\n\t\t\t//return point closest to the ray (positive side)\n\n\t\t\tif ( tmax < 0 ) return null;\n\n\t\t\treturn this.at( tmin >= 0 ? tmin : tmax, optionalTarget );\n\n\t\t},\n\n\t\tintersectsBox: ( function () {\n\n\t\t\tvar v = new Vector3();\n\n\t\t\treturn function intersectsBox( box ) {\n\n\t\t\t\treturn this.intersectBox( box, v ) !== null;\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tintersectTriangle: function () {\n\n\t\t\t// Compute the offset origin, edges, and normal.\n\t\t\tvar diff = new Vector3();\n\t\t\tvar edge1 = new Vector3();\n\t\t\tvar edge2 = new Vector3();\n\t\t\tvar normal = new Vector3();\n\n\t\t\treturn function intersectTriangle( a, b, c, backfaceCulling, optionalTarget ) {\n\n\t\t\t\t// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h\n\n\t\t\t\tedge1.subVectors( b, a );\n\t\t\t\tedge2.subVectors( c, a );\n\t\t\t\tnormal.crossVectors( edge1, edge2 );\n\n\t\t\t\t// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,\n\t\t\t\t// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by\n\t\t\t\t// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))\n\t\t\t\t// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))\n\t\t\t\t// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)\n\t\t\t\tvar DdN = this.direction.dot( normal );\n\t\t\t\tvar sign;\n\n\t\t\t\tif ( DdN > 0 ) {\n\n\t\t\t\t\tif ( backfaceCulling ) return null;\n\t\t\t\t\tsign = 1;\n\n\t\t\t\t} else if ( DdN < 0 ) {\n\n\t\t\t\t\tsign = - 1;\n\t\t\t\t\tDdN = - DdN;\n\n\t\t\t\t} else {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tdiff.subVectors( this.origin, a );\n\t\t\t\tvar DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) );\n\n\t\t\t\t// b1 < 0, no intersection\n\t\t\t\tif ( DdQxE2 < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\tvar DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) );\n\n\t\t\t\t// b2 < 0, no intersection\n\t\t\t\tif ( DdE1xQ < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// b1+b2 > 1, no intersection\n\t\t\t\tif ( DdQxE2 + DdE1xQ > DdN ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Line intersects triangle, check if ray does.\n\t\t\t\tvar QdN = - sign * diff.dot( normal );\n\n\t\t\t\t// t < 0, no intersection\n\t\t\t\tif ( QdN < 0 ) {\n\n\t\t\t\t\treturn null;\n\n\t\t\t\t}\n\n\t\t\t\t// Ray intersects triangle.\n\t\t\t\treturn this.at( QdN / DdN, optionalTarget );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tapplyMatrix4: function ( matrix4 ) {\n\n\t\t\tthis.direction.add( this.origin ).applyMatrix4( matrix4 );\n\t\t\tthis.origin.applyMatrix4( matrix4 );\n\t\t\tthis.direction.sub( this.origin );\n\t\t\tthis.direction.normalize();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( ray ) {\n\n\t\t\treturn ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Euler( x, y, z, order ) {\n\n\t\tthis._x = x || 0;\n\t\tthis._y = y || 0;\n\t\tthis._z = z || 0;\n\t\tthis._order = order || Euler.DefaultOrder;\n\n\t}\n\n\tEuler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];\n\n\tEuler.DefaultOrder = 'XYZ';\n\n\tEuler.prototype = {\n\n\t\tconstructor: Euler,\n\n\t\tisEuler: true,\n\n\t\tget x () {\n\n\t\t\treturn this._x;\n\n\t\t},\n\n\t\tset x ( value ) {\n\n\t\t\tthis._x = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget y () {\n\n\t\t\treturn this._y;\n\n\t\t},\n\n\t\tset y ( value ) {\n\n\t\t\tthis._y = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget z () {\n\n\t\t\treturn this._z;\n\n\t\t},\n\n\t\tset z ( value ) {\n\n\t\t\tthis._z = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tget order () {\n\n\t\t\treturn this._order;\n\n\t\t},\n\n\t\tset order ( value ) {\n\n\t\t\tthis._order = value;\n\t\t\tthis.onChangeCallback();\n\n\t\t},\n\n\t\tset: function ( x, y, z, order ) {\n\n\t\t\tthis._x = x;\n\t\t\tthis._y = y;\n\t\t\tthis._z = z;\n\t\t\tthis._order = order || this._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this._x, this._y, this._z, this._order );\n\n\t\t},\n\n\t\tcopy: function ( euler ) {\n\n\t\t\tthis._x = euler._x;\n\t\t\tthis._y = euler._y;\n\t\t\tthis._z = euler._z;\n\t\t\tthis._order = euler._order;\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromRotationMatrix: function ( m, order, update ) {\n\n\t\t\tvar clamp = _Math.clamp;\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tvar te = m.elements;\n\t\t\tvar m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];\n\t\t\tvar m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];\n\t\t\tvar m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];\n\n\t\t\torder = order || this._order;\n\n\t\t\tif ( order === 'XYZ' ) {\n\n\t\t\t\tthis._y = Math.asin( clamp( m13, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m13 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YXZ' ) {\n\n\t\t\t\tthis._x = Math.asin( - clamp( m23, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m23 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\t\t\t\t\tthis._z = 0;\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZXY' ) {\n\n\t\t\t\tthis._x = Math.asin( clamp( m32, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m32 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._y = Math.atan2( - m31, m33 );\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._y = 0;\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'ZYX' ) {\n\n\t\t\t\tthis._y = Math.asin( - clamp( m31, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m31 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m33 );\n\t\t\t\t\tthis._z = Math.atan2( m21, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._z = Math.atan2( - m12, m22 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'YZX' ) {\n\n\t\t\t\tthis._z = Math.asin( clamp( m21, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m21 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m22 );\n\t\t\t\t\tthis._y = Math.atan2( - m31, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = 0;\n\t\t\t\t\tthis._y = Math.atan2( m13, m33 );\n\n\t\t\t\t}\n\n\t\t\t} else if ( order === 'XZY' ) {\n\n\t\t\t\tthis._z = Math.asin( - clamp( m12, - 1, 1 ) );\n\n\t\t\t\tif ( Math.abs( m12 ) < 0.99999 ) {\n\n\t\t\t\t\tthis._x = Math.atan2( m32, m22 );\n\t\t\t\t\tthis._y = Math.atan2( m13, m11 );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis._x = Math.atan2( - m23, m33 );\n\t\t\t\t\tthis._y = 0;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order );\n\n\t\t\t}\n\n\t\t\tthis._order = order;\n\n\t\t\tif ( update !== false ) this.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromQuaternion: function () {\n\n\t\t\tvar matrix;\n\n\t\t\treturn function setFromQuaternion( q, order, update ) {\n\n\t\t\t\tif ( matrix === undefined ) matrix = new Matrix4();\n\n\t\t\t\tmatrix.makeRotationFromQuaternion( q );\n\n\t\t\t\treturn this.setFromRotationMatrix( matrix, order, update );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tsetFromVector3: function ( v, order ) {\n\n\t\t\treturn this.set( v.x, v.y, v.z, order || this._order );\n\n\t\t},\n\n\t\treorder: function () {\n\n\t\t\t// WARNING: this discards revolution information -bhouston\n\n\t\t\tvar q = new Quaternion();\n\n\t\t\treturn function reorder( newOrder ) {\n\n\t\t\t\tq.setFromEuler( this );\n\n\t\t\t\treturn this.setFromQuaternion( q, newOrder );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( euler ) {\n\n\t\t\treturn ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );\n\n\t\t},\n\n\t\tfromArray: function ( array ) {\n\n\t\t\tthis._x = array[ 0 ];\n\t\t\tthis._y = array[ 1 ];\n\t\t\tthis._z = array[ 2 ];\n\t\t\tif ( array[ 3 ] !== undefined ) this._order = array[ 3 ];\n\n\t\t\tthis.onChangeCallback();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoArray: function ( array, offset ) {\n\n\t\t\tif ( array === undefined ) array = [];\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tarray[ offset ] = this._x;\n\t\t\tarray[ offset + 1 ] = this._y;\n\t\t\tarray[ offset + 2 ] = this._z;\n\t\t\tarray[ offset + 3 ] = this._order;\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\ttoVector3: function ( optionalResult ) {\n\n\t\t\tif ( optionalResult ) {\n\n\t\t\t\treturn optionalResult.set( this._x, this._y, this._z );\n\n\t\t\t} else {\n\n\t\t\t\treturn new Vector3( this._x, this._y, this._z );\n\n\t\t\t}\n\n\t\t},\n\n\t\tonChange: function ( callback ) {\n\n\t\t\tthis.onChangeCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonChangeCallback: function () {}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Layers() {\n\n\t\tthis.mask = 1;\n\n\t}\n\n\tLayers.prototype = {\n\n\t\tconstructor: Layers,\n\n\t\tset: function ( channel ) {\n\n\t\t\tthis.mask = 1 << channel;\n\n\t\t},\n\n\t\tenable: function ( channel ) {\n\n\t\t\tthis.mask |= 1 << channel;\n\n\t\t},\n\n\t\ttoggle: function ( channel ) {\n\n\t\t\tthis.mask ^= 1 << channel;\n\n\t\t},\n\n\t\tdisable: function ( channel ) {\n\n\t\t\tthis.mask &= ~ ( 1 << channel );\n\n\t\t},\n\n\t\ttest: function ( layers ) {\n\n\t\t\treturn ( this.mask & layers.mask ) !== 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author elephantatwork / www.elephantatwork.ch\n\t */\n\n\tvar object3DId = 0;\n\n\tfunction Object3D() {\n\n\t\tObject.defineProperty( this, 'id', { value: object3DId ++ } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Object3D';\n\n\t\tthis.parent = null;\n\t\tthis.children = [];\n\n\t\tthis.up = Object3D.DefaultUp.clone();\n\n\t\tvar position = new Vector3();\n\t\tvar rotation = new Euler();\n\t\tvar quaternion = new Quaternion();\n\t\tvar scale = new Vector3( 1, 1, 1 );\n\n\t\tfunction onRotationChange() {\n\n\t\t\tquaternion.setFromEuler( rotation, false );\n\n\t\t}\n\n\t\tfunction onQuaternionChange() {\n\n\t\t\trotation.setFromQuaternion( quaternion, undefined, false );\n\n\t\t}\n\n\t\trotation.onChange( onRotationChange );\n\t\tquaternion.onChange( onQuaternionChange );\n\n\t\tObject.defineProperties( this, {\n\t\t\tposition: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: position\n\t\t\t},\n\t\t\trotation: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: rotation\n\t\t\t},\n\t\t\tquaternion: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: quaternion\n\t\t\t},\n\t\t\tscale: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: scale\n\t\t\t},\n\t\t\tmodelViewMatrix: {\n\t\t\t\tvalue: new Matrix4()\n\t\t\t},\n\t\t\tnormalMatrix: {\n\t\t\t\tvalue: new Matrix3()\n\t\t\t}\n\t\t} );\n\n\t\tthis.matrix = new Matrix4();\n\t\tthis.matrixWorld = new Matrix4();\n\n\t\tthis.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;\n\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\tthis.layers = new Layers();\n\t\tthis.visible = true;\n\n\t\tthis.castShadow = false;\n\t\tthis.receiveShadow = false;\n\n\t\tthis.frustumCulled = true;\n\t\tthis.renderOrder = 0;\n\n\t\tthis.userData = {};\n\n\t\tthis.onBeforeRender = function () {};\n\t\tthis.onAfterRender = function () {};\n\n\t}\n\n\tObject3D.DefaultUp = new Vector3( 0, 1, 0 );\n\tObject3D.DefaultMatrixAutoUpdate = true;\n\n\tObject3D.prototype = {\n\n\t\tconstructor: Object3D,\n\n\t\tisObject3D: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tthis.matrix.multiplyMatrices( matrix, this.matrix );\n\n\t\t\tthis.matrix.decompose( this.position, this.quaternion, this.scale );\n\n\t\t},\n\n\t\tsetRotationFromAxisAngle: function ( axis, angle ) {\n\n\t\t\t// assumes axis is normalized\n\n\t\t\tthis.quaternion.setFromAxisAngle( axis, angle );\n\n\t\t},\n\n\t\tsetRotationFromEuler: function ( euler ) {\n\n\t\t\tthis.quaternion.setFromEuler( euler, true );\n\n\t\t},\n\n\t\tsetRotationFromMatrix: function ( m ) {\n\n\t\t\t// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m );\n\n\t\t},\n\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\t// assumes q is normalized\n\n\t\t\tthis.quaternion.copy( q );\n\n\t\t},\n\n\t\trotateOnAxis: function () {\n\n\t\t\t// rotate object on axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar q1 = new Quaternion();\n\n\t\t\treturn function rotateOnAxis( axis, angle ) {\n\n\t\t\t\tq1.setFromAxisAngle( axis, angle );\n\n\t\t\t\tthis.quaternion.multiply( q1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\treturn this.rotateOnAxis( v1, angle );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateOnAxis: function () {\n\n\t\t\t// translate object by distance along axis in object space\n\t\t\t// axis is assumed to be normalized\n\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function translateOnAxis( axis, distance ) {\n\n\t\t\t\tv1.copy( axis ).applyQuaternion( this.quaternion );\n\n\t\t\t\tthis.position.add( v1.multiplyScalar( distance ) );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateX: function () {\n\n\t\t\tvar v1 = new Vector3( 1, 0, 0 );\n\n\t\t\treturn function translateX( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateY: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 1, 0 );\n\n\t\t\treturn function translateY( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslateZ: function () {\n\n\t\t\tvar v1 = new Vector3( 0, 0, 1 );\n\n\t\t\treturn function translateZ( distance ) {\n\n\t\t\t\treturn this.translateOnAxis( v1, distance );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlocalToWorld: function ( vector ) {\n\n\t\t\treturn vector.applyMatrix4( this.matrixWorld );\n\n\t\t},\n\n\t\tworldToLocal: function () {\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function worldToLocal( vector ) {\n\n\t\t\t\treturn vector.applyMatrix4( m1.getInverse( this.matrixWorld ) );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\t// This routine does not support objects with rotated and/or translated parent(s)\n\n\t\t\tvar m1 = new Matrix4();\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tm1.lookAt( vector, this.position, this.up );\n\n\t\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tadd: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.add( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( object === this ) {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object can't be added as a child of itself.\", object );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tif ( ( object && object.isObject3D ) ) {\n\n\t\t\t\tif ( object.parent !== null ) {\n\n\t\t\t\t\tobject.parent.remove( object );\n\n\t\t\t\t}\n\n\t\t\t\tobject.parent = this;\n\t\t\t\tobject.dispatchEvent( { type: 'added' } );\n\n\t\t\t\tthis.children.push( object );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( \"THREE.Object3D.add: object not an instance of THREE.Object3D.\", object );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tremove: function ( object ) {\n\n\t\t\tif ( arguments.length > 1 ) {\n\n\t\t\t\tfor ( var i = 0; i < arguments.length; i ++ ) {\n\n\t\t\t\t\tthis.remove( arguments[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar index = this.children.indexOf( object );\n\n\t\t\tif ( index !== - 1 ) {\n\n\t\t\t\tobject.parent = null;\n\n\t\t\t\tobject.dispatchEvent( { type: 'removed' } );\n\n\t\t\t\tthis.children.splice( index, 1 );\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetObjectById: function ( id ) {\n\n\t\t\treturn this.getObjectByProperty( 'id', id );\n\n\t\t},\n\n\t\tgetObjectByName: function ( name ) {\n\n\t\t\treturn this.getObjectByProperty( 'name', name );\n\n\t\t},\n\n\t\tgetObjectByProperty: function ( name, value ) {\n\n\t\t\tif ( this[ name ] === value ) return this;\n\n\t\t\tfor ( var i = 0, l = this.children.length; i < l; i ++ ) {\n\n\t\t\t\tvar child = this.children[ i ];\n\t\t\t\tvar object = child.getObjectByProperty( name, value );\n\n\t\t\t\tif ( object !== undefined ) {\n\n\t\t\t\t\treturn object;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\n\t\t},\n\n\t\tgetWorldPosition: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\treturn result.setFromMatrixPosition( this.matrixWorld );\n\n\t\t},\n\n\t\tgetWorldQuaternion: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar scale = new Vector3();\n\n\t\t\treturn function getWorldQuaternion( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Quaternion();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, result, scale );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldRotation: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldRotation( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Euler();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.setFromQuaternion( quaternion, this.rotation.order, false );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldScale: function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldScale( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, result );\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tgetWorldDirection: function () {\n\n\t\t\tvar quaternion = new Quaternion();\n\n\t\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\t\treturn result.set( 0, 0, 1 ).applyQuaternion( quaternion );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\traycast: function () {},\n\n\t\ttraverse: function ( callback ) {\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverse( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseVisible: function ( callback ) {\n\n\t\t\tif ( this.visible === false ) return;\n\n\t\t\tcallback( this );\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].traverseVisible( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttraverseAncestors: function ( callback ) {\n\n\t\t\tvar parent = this.parent;\n\n\t\t\tif ( parent !== null ) {\n\n\t\t\t\tcallback( parent );\n\n\t\t\t\tparent.traverseAncestors( callback );\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrix: function () {\n\n\t\t\tthis.matrix.compose( this.position, this.quaternion, this.scale );\n\n\t\t\tthis.matrixWorldNeedsUpdate = true;\n\n\t\t},\n\n\t\tupdateMatrixWorld: function ( force ) {\n\n\t\t\tif ( this.matrixAutoUpdate === true ) this.updateMatrix();\n\n\t\t\tif ( this.matrixWorldNeedsUpdate === true || force === true ) {\n\n\t\t\t\tif ( this.parent === null ) {\n\n\t\t\t\t\tthis.matrixWorld.copy( this.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\n\t\t\t\tforce = true;\n\n\t\t\t}\n\n\t\t\t// update children\n\n\t\t\tvar children = this.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tchildren[ i ].updateMatrixWorld( force );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\t// meta is '' when called from JSON.stringify\n\t\t\tvar isRootObject = ( meta === undefined || meta === '' );\n\n\t\t\tvar output = {};\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\t// initialize meta obj\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {}\n\t\t\t\t};\n\n\t\t\t\toutput.metadata = {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON'\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t// standard Object3D serialization\n\n\t\t\tvar object = {};\n\n\t\t\tobject.uuid = this.uuid;\n\t\t\tobject.type = this.type;\n\n\t\t\tif ( this.name !== '' ) object.name = this.name;\n\t\t\tif ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;\n\t\t\tif ( this.castShadow === true ) object.castShadow = true;\n\t\t\tif ( this.receiveShadow === true ) object.receiveShadow = true;\n\t\t\tif ( this.visible === false ) object.visible = false;\n\n\t\t\tobject.matrix = this.matrix.toArray();\n\n\t\t\t//\n\n\t\t\tif ( this.geometry !== undefined ) {\n\n\t\t\t\tif ( meta.geometries[ this.geometry.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.geometries[ this.geometry.uuid ] = this.geometry.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.geometry = this.geometry.uuid;\n\n\t\t\t}\n\n\t\t\tif ( this.material !== undefined ) {\n\n\t\t\t\tif ( meta.materials[ this.material.uuid ] === undefined ) {\n\n\t\t\t\t\tmeta.materials[ this.material.uuid ] = this.material.toJSON( meta );\n\n\t\t\t\t}\n\n\t\t\t\tobject.material = this.material.uuid;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( this.children.length > 0 ) {\n\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor ( var i = 0; i < this.children.length; i ++ ) {\n\n\t\t\t\t\tobject.children.push( this.children[ i ].toJSON( meta ).object );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( isRootObject ) {\n\n\t\t\t\tvar geometries = extractFromCache( meta.geometries );\n\t\t\t\tvar materials = extractFromCache( meta.materials );\n\t\t\t\tvar textures = extractFromCache( meta.textures );\n\t\t\t\tvar images = extractFromCache( meta.images );\n\n\t\t\t\tif ( geometries.length > 0 ) output.geometries = geometries;\n\t\t\t\tif ( materials.length > 0 ) output.materials = materials;\n\t\t\t\tif ( textures.length > 0 ) output.textures = textures;\n\t\t\t\tif ( images.length > 0 ) output.images = images;\n\n\t\t\t}\n\n\t\t\toutput.object = object;\n\n\t\t\treturn output;\n\n\t\t\t// extract data from the cache hash\n\t\t\t// remove metadata on each item\n\t\t\t// and return as array\n\t\t\tfunction extractFromCache( cache ) {\n\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var key in cache ) {\n\n\t\t\t\t\tvar data = cache[ key ];\n\t\t\t\t\tdelete data.metadata;\n\t\t\t\t\tvalues.push( data );\n\n\t\t\t\t}\n\t\t\t\treturn values;\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function ( recursive ) {\n\n\t\t\treturn new this.constructor().copy( this, recursive );\n\n\t\t},\n\n\t\tcopy: function ( source, recursive ) {\n\n\t\t\tif ( recursive === undefined ) recursive = true;\n\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy( source.up );\n\n\t\t\tthis.position.copy( source.position );\n\t\t\tthis.quaternion.copy( source.quaternion );\n\t\t\tthis.scale.copy( source.scale );\n\n\t\t\tthis.matrix.copy( source.matrix );\n\t\t\tthis.matrixWorld.copy( source.matrixWorld );\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\tthis.userData = JSON.parse( JSON.stringify( source.userData ) );\n\n\t\t\tif ( recursive === true ) {\n\n\t\t\t\tfor ( var i = 0; i < source.children.length; i ++ ) {\n\n\t\t\t\t\tvar child = source.children[ i ];\n\t\t\t\t\tthis.add( child.clone() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tObject.assign( Object3D.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t */\n\n\tfunction Line3( start, end ) {\n\n\t\tthis.start = ( start !== undefined ) ? start : new Vector3();\n\t\tthis.end = ( end !== undefined ) ? end : new Vector3();\n\n\t}\n\n\tLine3.prototype = {\n\n\t\tconstructor: Line3,\n\n\t\tset: function ( start, end ) {\n\n\t\t\tthis.start.copy( start );\n\t\t\tthis.end.copy( end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( line ) {\n\n\t\t\tthis.start.copy( line.start );\n\t\t\tthis.end.copy( line.end );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetCenter: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.start, this.end ).multiplyScalar( 0.5 );\n\n\t\t},\n\n\t\tdelta: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.subVectors( this.end, this.start );\n\n\t\t},\n\n\t\tdistanceSq: function () {\n\n\t\t\treturn this.start.distanceToSquared( this.end );\n\n\t\t},\n\n\t\tdistance: function () {\n\n\t\t\treturn this.start.distanceTo( this.end );\n\n\t\t},\n\n\t\tat: function ( t, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tclosestPointToPointParameter: function () {\n\n\t\t\tvar startP = new Vector3();\n\t\t\tvar startEnd = new Vector3();\n\n\t\t\treturn function closestPointToPointParameter( point, clampToLine ) {\n\n\t\t\t\tstartP.subVectors( point, this.start );\n\t\t\t\tstartEnd.subVectors( this.end, this.start );\n\n\t\t\t\tvar startEnd2 = startEnd.dot( startEnd );\n\t\t\t\tvar startEnd_startP = startEnd.dot( startP );\n\n\t\t\t\tvar t = startEnd_startP / startEnd2;\n\n\t\t\t\tif ( clampToLine ) {\n\n\t\t\t\t\tt = _Math.clamp( t, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t\treturn t;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tclosestPointToPoint: function ( point, clampToLine, optionalTarget ) {\n\n\t\t\tvar t = this.closestPointToPointParameter( point, clampToLine );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\treturn this.delta( result ).multiplyScalar( t ).add( this.start );\n\n\t\t},\n\n\t\tapplyMatrix4: function ( matrix ) {\n\n\t\t\tthis.start.applyMatrix4( matrix );\n\t\t\tthis.end.applyMatrix4( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tequals: function ( line ) {\n\n\t\t\treturn line.start.equals( this.start ) && line.end.equals( this.end );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Triangle( a, b, c ) {\n\n\t\tthis.a = ( a !== undefined ) ? a : new Vector3();\n\t\tthis.b = ( b !== undefined ) ? b : new Vector3();\n\t\tthis.c = ( c !== undefined ) ? c : new Vector3();\n\n\t}\n\n\tTriangle.normal = function () {\n\n\t\tvar v0 = new Vector3();\n\n\t\treturn function normal( a, b, c, optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tresult.subVectors( c, b );\n\t\t\tv0.subVectors( a, b );\n\t\t\tresult.cross( v0 );\n\n\t\t\tvar resultLengthSq = result.lengthSq();\n\t\t\tif ( resultLengthSq > 0 ) {\n\n\t\t\t\treturn result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );\n\n\t\t\t}\n\n\t\t\treturn result.set( 0, 0, 0 );\n\n\t\t};\n\n\t}();\n\n\t// static/instance method to calculate barycentric coordinates\n\t// based on: http://www.blackpawn.com/texts/pointinpoly/default.html\n\tTriangle.barycoordFromPoint = function () {\n\n\t\tvar v0 = new Vector3();\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\n\t\treturn function barycoordFromPoint( point, a, b, c, optionalTarget ) {\n\n\t\t\tv0.subVectors( c, a );\n\t\t\tv1.subVectors( b, a );\n\t\t\tv2.subVectors( point, a );\n\n\t\t\tvar dot00 = v0.dot( v0 );\n\t\t\tvar dot01 = v0.dot( v1 );\n\t\t\tvar dot02 = v0.dot( v2 );\n\t\t\tvar dot11 = v1.dot( v1 );\n\t\t\tvar dot12 = v1.dot( v2 );\n\n\t\t\tvar denom = ( dot00 * dot11 - dot01 * dot01 );\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\t// collinear or singular triangle\n\t\t\tif ( denom === 0 ) {\n\n\t\t\t\t// arbitrary location outside of triangle?\n\t\t\t\t// not sure if this is the best idea, maybe should be returning undefined\n\t\t\t\treturn result.set( - 2, - 1, - 1 );\n\n\t\t\t}\n\n\t\t\tvar invDenom = 1 / denom;\n\t\t\tvar u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;\n\t\t\tvar v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;\n\n\t\t\t// barycentric coordinates must always sum to 1\n\t\t\treturn result.set( 1 - u - v, v, u );\n\n\t\t};\n\n\t}();\n\n\tTriangle.containsPoint = function () {\n\n\t\tvar v1 = new Vector3();\n\n\t\treturn function containsPoint( point, a, b, c ) {\n\n\t\t\tvar result = Triangle.barycoordFromPoint( point, a, b, c, v1 );\n\n\t\t\treturn ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );\n\n\t\t};\n\n\t}();\n\n\tTriangle.prototype = {\n\n\t\tconstructor: Triangle,\n\n\t\tset: function ( a, b, c ) {\n\n\t\t\tthis.a.copy( a );\n\t\t\tthis.b.copy( b );\n\t\t\tthis.c.copy( c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromPointsAndIndices: function ( points, i0, i1, i2 ) {\n\n\t\t\tthis.a.copy( points[ i0 ] );\n\t\t\tthis.b.copy( points[ i1 ] );\n\t\t\tthis.c.copy( points[ i2 ] );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( triangle ) {\n\n\t\t\tthis.a.copy( triangle.a );\n\t\t\tthis.b.copy( triangle.b );\n\t\t\tthis.c.copy( triangle.c );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tarea: function () {\n\n\t\t\tvar v0 = new Vector3();\n\t\t\tvar v1 = new Vector3();\n\n\t\t\treturn function area() {\n\n\t\t\t\tv0.subVectors( this.c, this.b );\n\t\t\t\tv1.subVectors( this.a, this.b );\n\n\t\t\t\treturn v0.cross( v1 ).length() * 0.5;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tmidpoint: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\treturn result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );\n\n\t\t},\n\n\t\tnormal: function ( optionalTarget ) {\n\n\t\t\treturn Triangle.normal( this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tplane: function ( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Plane();\n\n\t\t\treturn result.setFromCoplanarPoints( this.a, this.b, this.c );\n\n\t\t},\n\n\t\tbarycoordFromPoint: function ( point, optionalTarget ) {\n\n\t\t\treturn Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );\n\n\t\t},\n\n\t\tcontainsPoint: function ( point ) {\n\n\t\t\treturn Triangle.containsPoint( point, this.a, this.b, this.c );\n\n\t\t},\n\n\t\tclosestPointToPoint: function () {\n\n\t\t\tvar plane, edgeList, projectedPoint, closestPoint;\n\n\t\t\treturn function closestPointToPoint( point, optionalTarget ) {\n\n\t\t\t\tif ( plane === undefined ) {\n\n\t\t\t\t\tplane = new Plane();\n\t\t\t\t\tedgeList = [ new Line3(), new Line3(), new Line3() ];\n\t\t\t\t\tprojectedPoint = new Vector3();\n\t\t\t\t\tclosestPoint = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tvar result = optionalTarget || new Vector3();\n\t\t\t\tvar minDistance = Infinity;\n\n\t\t\t\t// project the point onto the plane of the triangle\n\n\t\t\t\tplane.setFromCoplanarPoints( this.a, this.b, this.c );\n\t\t\t\tplane.projectPoint( point, projectedPoint );\n\n\t\t\t\t// check if the projection lies within the triangle\n\n\t\t\t\tif( this.containsPoint( projectedPoint ) === true ) {\n\n\t\t\t\t\t// if so, this is the closest point\n\n\t\t\t\t\tresult.copy( projectedPoint );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices\n\n\t\t\t\t\tedgeList[ 0 ].set( this.a, this.b );\n\t\t\t\t\tedgeList[ 1 ].set( this.b, this.c );\n\t\t\t\t\tedgeList[ 2 ].set( this.c, this.a );\n\n\t\t\t\t\tfor( var i = 0; i < edgeList.length; i ++ ) {\n\n\t\t\t\t\t\tedgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );\n\n\t\t\t\t\t\tvar distance = projectedPoint.distanceToSquared( closestPoint );\n\n\t\t\t\t\t\tif( distance < minDistance ) {\n\n\t\t\t\t\t\t\tminDistance = distance;\n\n\t\t\t\t\t\t\tresult.copy( closestPoint );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tequals: function ( triangle ) {\n\n\t\t\treturn triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Face3( a, b, c, normal, color, materialIndex ) {\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.c = c;\n\n\t\tthis.normal = (normal && normal.isVector3) ? normal : new Vector3();\n\t\tthis.vertexNormals = Array.isArray( normal ) ? normal : [];\n\n\t\tthis.color = (color && color.isColor) ? color : new Color();\n\t\tthis.vertexColors = Array.isArray( color ) ? color : [];\n\n\t\tthis.materialIndex = materialIndex !== undefined ? materialIndex : 0;\n\n\t}\n\n\tFace3.prototype = {\n\n\t\tconstructor: Face3,\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.a = source.a;\n\t\t\tthis.b = source.b;\n\t\t\tthis.c = source.c;\n\n\t\t\tthis.normal.copy( source.normal );\n\t\t\tthis.color.copy( source.color );\n\n\t\t\tthis.materialIndex = source.materialIndex;\n\n\t\t\tfor ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexNormals[ i ] = source.vertexNormals[ i ].clone();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertexColors[ i ] = source.vertexColors[ i ].clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * shading: THREE.SmoothShading,\n\t * depthTest: ,\n\t * depthWrite: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: \n\t * }\n\t */\n\n\tfunction MeshBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // emissive\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshBasicMaterial.prototype = Object.create( Material.prototype );\n\tMeshBasicMaterial.prototype.constructor = MeshBasicMaterial;\n\n\tMeshBasicMaterial.prototype.isMeshBasicMaterial = true;\n\n\tMeshBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferAttribute( array, itemSize, normalized ) {\n\n\t\tif ( Array.isArray( array ) ) {\n\n\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t}\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.itemSize = itemSize;\n\t\tthis.count = array !== undefined ? array.length / itemSize : 0;\n\t\tthis.normalized = normalized === true;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tBufferAttribute.prototype = {\n\n\t\tconstructor: BufferAttribute,\n\n\t\tisBufferAttribute: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.itemSize : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.itemSize = source.itemSize;\n\t\t\tthis.count = source.count;\n\t\t\tthis.normalized = source.normalized;\n\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.itemSize;\n\t\t\tindex2 *= attribute.itemSize;\n\n\t\t\tfor ( var i = 0, l = this.itemSize; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyArray: function ( array ) {\n\n\t\t\tthis.array.set( array );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyColorsArray: function ( colors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = colors.length; i < l; i ++ ) {\n\n\t\t\t\tvar color = colors[ i ];\n\n\t\t\t\tif ( color === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );\n\t\t\t\t\tcolor = new Color();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = color.r;\n\t\t\t\tarray[ offset ++ ] = color.g;\n\t\t\t\tarray[ offset ++ ] = color.b;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyIndicesArray: function ( indices ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\tvar index = indices[ i ];\n\n\t\t\t\tarray[ offset ++ ] = index.a;\n\t\t\t\tarray[ offset ++ ] = index.b;\n\t\t\t\tarray[ offset ++ ] = index.c;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector2sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector2();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector3sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector3();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyVector4sArray: function ( vectors ) {\n\n\t\t\tvar array = this.array, offset = 0;\n\n\t\t\tfor ( var i = 0, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tvar vector = vectors[ i ];\n\n\t\t\t\tif ( vector === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );\n\t\t\t\t\tvector = new Vector4();\n\n\t\t\t\t}\n\n\t\t\t\tarray[ offset ++ ] = vector.x;\n\t\t\t\tarray[ offset ++ ] = vector.y;\n\t\t\t\tarray[ offset ++ ] = vector.z;\n\t\t\t\tarray[ offset ++ ] = vector.w;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize ];\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.array[ index * this.itemSize ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 1 ];\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.array[ index * this.itemSize + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 2 ];\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.array[ index * this.itemSize + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.array[ index * this.itemSize + 3 ];\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.array[ index * this.itemSize + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex *= this.itemSize;\n\n\t\t\tthis.array[ index + 0 ] = x;\n\t\t\tthis.array[ index + 1 ] = y;\n\t\t\tthis.array[ index + 2 ] = z;\n\t\t\tthis.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.array, this.itemSize ).copy( this );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Int8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int8Array( array ), itemSize );\n\n\t}\n\n\tInt8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt8BufferAttribute.prototype.constructor = Int8BufferAttribute;\n\n\n\tfunction Uint8BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8Array( array ), itemSize );\n\n\t}\n\n\tUint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;\n\n\n\tfunction Uint8ClampedBufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize );\n\n\t}\n\n\tUint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;\n\n\n\tfunction Int16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int16Array( array ), itemSize );\n\n\t}\n\n\tInt16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt16BufferAttribute.prototype.constructor = Int16BufferAttribute;\n\n\n\tfunction Uint16BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint16Array( array ), itemSize );\n\n\t}\n\n\tUint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;\n\n\n\tfunction Int32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Int32Array( array ), itemSize );\n\n\t}\n\n\tInt32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInt32BufferAttribute.prototype.constructor = Int32BufferAttribute;\n\n\n\tfunction Uint32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Uint32Array( array ), itemSize );\n\n\t}\n\n\tUint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tUint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;\n\n\n\tfunction Float32BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float32Array( array ), itemSize );\n\n\t}\n\n\tFloat32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat32BufferAttribute.prototype.constructor = Float32BufferAttribute;\n\n\n\tfunction Float64BufferAttribute( array, itemSize ) {\n\n\t\tBufferAttribute.call( this, new Float64Array( array ), itemSize );\n\n\t}\n\n\tFloat64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tFloat64BufferAttribute.prototype.constructor = Float64BufferAttribute;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectGeometry() {\n\n\t\tthis.indices = [];\n\t\tthis.vertices = [];\n\t\tthis.normals = [];\n\t\tthis.colors = [];\n\t\tthis.uvs = [];\n\t\tthis.uvs2 = [];\n\n\t\tthis.groups = [];\n\n\t\tthis.morphTargets = {};\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\t// this.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tObject.assign( DirectGeometry.prototype, {\n\n\t\tcomputeGroups: function ( geometry ) {\n\n\t\t\tvar group;\n\t\t\tvar groups = [];\n\t\t\tvar materialIndex = undefined;\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t// materials\n\n\t\t\t\tif ( face.materialIndex !== materialIndex ) {\n\n\t\t\t\t\tmaterialIndex = face.materialIndex;\n\n\t\t\t\t\tif ( group !== undefined ) {\n\n\t\t\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\t\t\tgroups.push( group );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgroup = {\n\t\t\t\t\t\tstart: i * 3,\n\t\t\t\t\t\tmaterialIndex: materialIndex\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( group !== undefined ) {\n\n\t\t\t\tgroup.count = ( i * 3 ) - group.start;\n\t\t\t\tgroups.push( group );\n\n\t\t\t}\n\n\t\t\tthis.groups = groups;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tvar faces = geometry.faces;\n\t\t\tvar vertices = geometry.vertices;\n\t\t\tvar faceVertexUvs = geometry.faceVertexUvs;\n\n\t\t\tvar hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;\n\t\t\tvar hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;\n\n\t\t\t// morphs\n\n\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\tvar morphTargetsLength = morphTargets.length;\n\n\t\t\tvar morphTargetsPosition;\n\n\t\t\tif ( morphTargetsLength > 0 ) {\n\n\t\t\t\tmorphTargetsPosition = [];\n\n\t\t\t\tfor ( var i = 0; i < morphTargetsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsPosition[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.position = morphTargetsPosition;\n\n\t\t\t}\n\n\t\t\tvar morphNormals = geometry.morphNormals;\n\t\t\tvar morphNormalsLength = morphNormals.length;\n\n\t\t\tvar morphTargetsNormal;\n\n\t\t\tif ( morphNormalsLength > 0 ) {\n\n\t\t\t\tmorphTargetsNormal = [];\n\n\t\t\t\tfor ( var i = 0; i < morphNormalsLength; i ++ ) {\n\n\t\t\t\t\tmorphTargetsNormal[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.normal = morphTargetsNormal;\n\n\t\t\t}\n\n\t\t\t// skins\n\n\t\t\tvar skinIndices = geometry.skinIndices;\n\t\t\tvar skinWeights = geometry.skinWeights;\n\n\t\t\tvar hasSkinIndices = skinIndices.length === vertices.length;\n\t\t\tvar hasSkinWeights = skinWeights.length === vertices.length;\n\n\t\t\t//\n\n\t\t\tfor ( var i = 0; i < faces.length; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tthis.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tthis.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar normal = face.normal;\n\n\t\t\t\t\tthis.normals.push( normal, normal, normal );\n\n\t\t\t\t}\n\n\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\tif ( vertexColors.length === 3 ) {\n\n\t\t\t\t\tthis.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar color = face.color;\n\n\t\t\t\t\tthis.colors.push( color, color, color );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );\n\n\t\t\t\t\t\tthis.uvs.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexUv2 === true ) {\n\n\t\t\t\t\tvar vertexUvs = faceVertexUvs[ 1 ][ i ];\n\n\t\t\t\t\tif ( vertexUvs !== undefined ) {\n\n\t\t\t\t\t\tthis.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );\n\n\t\t\t\t\t\tthis.uvs2.push( new Vector2(), new Vector2(), new Vector2() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// morphs\n\n\t\t\t\tfor ( var j = 0; j < morphTargetsLength; j ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ j ].vertices;\n\n\t\t\t\t\tmorphTargetsPosition[ j ].push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0; j < morphNormalsLength; j ++ ) {\n\n\t\t\t\t\tvar morphNormal = morphNormals[ j ].vertexNormals[ i ];\n\n\t\t\t\t\tmorphTargetsNormal[ j ].push( morphNormal.a, morphNormal.b, morphNormal.c );\n\n\t\t\t\t}\n\n\t\t\t\t// skins\n\n\t\t\t\tif ( hasSkinIndices ) {\n\n\t\t\t\t\tthis.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasSkinWeights ) {\n\n\t\t\t\t\tthis.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeGroups( geometry );\n\n\t\t\tthis.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values/13440842#13440842\n\n\tfunction arrayMax( array ) {\n\n\t\tvar length = array.length, max = - Infinity;\n\n\t\twhile ( length -- ) {\n\n\t\t\tif ( array[ length ] > max ) {\n\n\t\t\t\tmax = array[ length ];\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn max;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author kile / http://kile.stravaganza.org/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author bhouston / http://clara.io\n\t */\n\n\tvar count = 0;\n\tfunction GeometryIdCount() { return count++; }\n\n\tfunction Geometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'Geometry';\n\n\t\tthis.vertices = [];\n\t\tthis.colors = [];\n\t\tthis.faces = [];\n\t\tthis.faceVertexUvs = [[]];\n\n\t\tthis.morphTargets = [];\n\t\tthis.morphNormals = [];\n\n\t\tthis.skinWeights = [];\n\t\tthis.skinIndices = [];\n\n\t\tthis.lineDistances = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\t// update flags\n\n\t\tthis.elementsNeedUpdate = false;\n\t\tthis.verticesNeedUpdate = false;\n\t\tthis.uvsNeedUpdate = false;\n\t\tthis.normalsNeedUpdate = false;\n\t\tthis.colorsNeedUpdate = false;\n\t\tthis.lineDistancesNeedUpdate = false;\n\t\tthis.groupsNeedUpdate = false;\n\n\t}\n\n\tGeometry.prototype = {\n\n\t\tconstructor: Geometry,\n\n\t\tisGeometry: true,\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\tfor ( var i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertex.applyMatrix4( matrix );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\t\t\t\tface.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tface.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\tthis.verticesNeedUpdate = true;\n\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tfromBufferGeometry: function ( geometry ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar indices = geometry.index !== null ? geometry.index.array : undefined;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tvar positions = attributes.position.array;\n\t\t\tvar normals = attributes.normal !== undefined ? attributes.normal.array : undefined;\n\t\t\tvar colors = attributes.color !== undefined ? attributes.color.array : undefined;\n\t\t\tvar uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;\n\t\t\tvar uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;\n\n\t\t\tif ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];\n\n\t\t\tvar tempNormals = [];\n\t\t\tvar tempUVs = [];\n\t\t\tvar tempUVs2 = [];\n\n\t\t\tfor ( var i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {\n\n\t\t\t\tscope.vertices.push( new Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] ) );\n\n\t\t\t\tif ( normals !== undefined ) {\n\n\t\t\t\t\ttempNormals.push( new Vector3( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( colors !== undefined ) {\n\n\t\t\t\t\tscope.colors.push( new Color( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\ttempUVs.push( new Vector2( uvs[ j ], uvs[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\ttempUVs2.push( new Vector2( uvs2[ j ], uvs2[ j + 1 ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction addFace( a, b, c, materialIndex ) {\n\n\t\t\t\tvar vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : [];\n\t\t\t\tvar vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : [];\n\n\t\t\t\tvar face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );\n\n\t\t\t\tscope.faces.push( face );\n\n\t\t\t\tif ( uvs !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 0 ].push( [ tempUVs[ a ].clone(), tempUVs[ b ].clone(), tempUVs[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t\tif ( uvs2 !== undefined ) {\n\n\t\t\t\t\tscope.faceVertexUvs[ 1 ].push( [ tempUVs2[ a ].clone(), tempUVs2[ b ].clone(), tempUVs2[ c ].clone() ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( indices !== undefined ) {\n\n\t\t\t\tvar groups = geometry.groups;\n\n\t\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\t\tfor ( var i = 0; i < groups.length; i ++ ) {\n\n\t\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var j = start, jl = start + count; j < jl; j += 3 ) {\n\n\t\t\t\t\t\t\taddFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t\t\taddFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tfor ( var i = 0; i < positions.length / 3; i += 3 ) {\n\n\t\t\t\t\taddFace( i, i + 1, i + 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tnormalize: function () {\n\n\t\t\tthis.computeBoundingSphere();\n\n\t\t\tvar center = this.boundingSphere.center;\n\t\t\tvar radius = this.boundingSphere.radius;\n\n\t\t\tvar s = radius === 0 ? 1 : 1.0 / radius;\n\n\t\t\tvar matrix = new Matrix4();\n\t\t\tmatrix.set(\n\t\t\t\ts, 0, 0, - s * center.x,\n\t\t\t\t0, s, 0, - s * center.y,\n\t\t\t\t0, 0, s, - s * center.z,\n\t\t\t\t0, 0, 0, 1\n\t\t\t);\n\n\t\t\tthis.applyMatrix( matrix );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\tfor ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tvar face = this.faces[ f ];\n\n\t\t\t\tvar vA = this.vertices[ face.a ];\n\t\t\t\tvar vB = this.vertices[ face.b ];\n\t\t\t\tvar vC = this.vertices[ face.c ];\n\n\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\tcb.cross( ab );\n\n\t\t\t\tcb.normalize();\n\n\t\t\t\tface.normal.copy( cb );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeVertexNormals: function ( areaWeighted ) {\n\n\t\t\tif ( areaWeighted === undefined ) areaWeighted = true;\n\n\t\t\tvar v, vl, f, fl, face, vertices;\n\n\t\t\tvertices = new Array( this.vertices.length );\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ] = new Vector3();\n\n\t\t\t}\n\n\t\t\tif ( areaWeighted ) {\n\n\t\t\t\t// vertex normals weighted by triangle areas\n\t\t\t\t// http://www.iquilezles.org/www/articles/normals/normals.htm\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvA = this.vertices[ face.a ];\n\t\t\t\t\tvB = this.vertices[ face.b ];\n\t\t\t\t\tvC = this.vertices[ face.c ];\n\n\t\t\t\t\tcb.subVectors( vC, vB );\n\t\t\t\t\tab.subVectors( vA, vB );\n\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\tvertices[ face.a ].add( cb );\n\t\t\t\t\tvertices[ face.b ].add( cb );\n\t\t\t\t\tvertices[ face.c ].add( cb );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tthis.computeFaceNormals();\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tvertices[ face.a ].add( face.normal );\n\t\t\t\t\tvertices[ face.b ].add( face.normal );\n\t\t\t\t\tvertices[ face.c ].add( face.normal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {\n\n\t\t\t\tvertices[ v ].normalize();\n\n\t\t\t}\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( vertices[ face.a ] );\n\t\t\t\t\tvertexNormals[ 1 ].copy( vertices[ face.b ] );\n\t\t\t\t\tvertexNormals[ 2 ].copy( vertices[ face.c ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = vertices[ face.a ].clone();\n\t\t\t\t\tvertexNormals[ 1 ] = vertices[ face.b ].clone();\n\t\t\t\t\tvertexNormals[ 2 ] = vertices[ face.c ].clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeFlatVertexNormals: function () {\n\n\t\t\tvar f, fl, face;\n\n\t\t\tthis.computeFaceNormals();\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\tif ( vertexNormals.length === 3 ) {\n\n\t\t\t\t\tvertexNormals[ 0 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 1 ].copy( face.normal );\n\t\t\t\t\tvertexNormals[ 2 ].copy( face.normal );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvertexNormals[ 0 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 1 ] = face.normal.clone();\n\t\t\t\t\tvertexNormals[ 2 ] = face.normal.clone();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( this.faces.length > 0 ) {\n\n\t\t\t\tthis.normalsNeedUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeMorphNormals: function () {\n\n\t\t\tvar i, il, f, fl, face;\n\n\t\t\t// save original normals\n\t\t\t// - create temp variables on first access\n\t\t\t// otherwise just copy (for faster repeated calls)\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tif ( ! face.__originalFaceNormal ) {\n\n\t\t\t\t\tface.__originalFaceNormal = face.normal.clone();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tface.__originalFaceNormal.copy( face.normal );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];\n\n\t\t\t\tfor ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {\n\n\t\t\t\t\tif ( ! face.__originalVertexNormals[ i ] ) {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// use temp geometry to compute face and vertex normals for each morph\n\n\t\t\tvar tmpGeo = new Geometry();\n\t\t\ttmpGeo.faces = this.faces;\n\n\t\t\tfor ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\t// create on first access\n\n\t\t\t\tif ( ! this.morphNormals[ i ] ) {\n\n\t\t\t\t\tthis.morphNormals[ i ] = {};\n\t\t\t\t\tthis.morphNormals[ i ].faceNormals = [];\n\t\t\t\t\tthis.morphNormals[ i ].vertexNormals = [];\n\n\t\t\t\t\tvar dstNormalsFace = this.morphNormals[ i ].faceNormals;\n\t\t\t\t\tvar dstNormalsVertex = this.morphNormals[ i ].vertexNormals;\n\n\t\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tfaceNormal = new Vector3();\n\t\t\t\t\t\tvertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };\n\n\t\t\t\t\t\tdstNormalsFace.push( faceNormal );\n\t\t\t\t\t\tdstNormalsVertex.push( vertexNormals );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar morphNormals = this.morphNormals[ i ];\n\n\t\t\t\t// set vertices to morph target\n\n\t\t\t\ttmpGeo.vertices = this.morphTargets[ i ].vertices;\n\n\t\t\t\t// compute morph normals\n\n\t\t\t\ttmpGeo.computeFaceNormals();\n\t\t\t\ttmpGeo.computeVertexNormals();\n\n\t\t\t\t// store morph normals\n\n\t\t\t\tvar faceNormal, vertexNormals;\n\n\t\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\t\tfaceNormal = morphNormals.faceNormals[ f ];\n\t\t\t\t\tvertexNormals = morphNormals.vertexNormals[ f ];\n\n\t\t\t\t\tfaceNormal.copy( face.normal );\n\n\t\t\t\t\tvertexNormals.a.copy( face.vertexNormals[ 0 ] );\n\t\t\t\t\tvertexNormals.b.copy( face.vertexNormals[ 1 ] );\n\t\t\t\t\tvertexNormals.c.copy( face.vertexNormals[ 2 ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// restore original normals\n\n\t\t\tfor ( f = 0, fl = this.faces.length; f < fl; f ++ ) {\n\n\t\t\t\tface = this.faces[ f ];\n\n\t\t\t\tface.normal = face.__originalFaceNormal;\n\t\t\t\tface.vertexNormals = face.__originalVertexNormals;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeLineDistances: function () {\n\n\t\t\tvar d = 0;\n\t\t\tvar vertices = this.vertices;\n\n\t\t\tfor ( var i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tif ( i > 0 ) {\n\n\t\t\t\t\td += vertices[ i ].distanceTo( vertices[ i - 1 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.lineDistances[ i ] = d;\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tthis.boundingBox.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t}\n\n\t\t\tthis.boundingSphere.setFromPoints( this.vertices );\n\n\t\t},\n\n\t\tmerge: function ( geometry, matrix, materialIndexOffset ) {\n\n\t\t\tif ( ( geometry && geometry.isGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar normalMatrix,\n\t\t\tvertexOffset = this.vertices.length,\n\t\t\tvertices1 = this.vertices,\n\t\t\tvertices2 = geometry.vertices,\n\t\t\tfaces1 = this.faces,\n\t\t\tfaces2 = geometry.faces,\n\t\t\tuvs1 = this.faceVertexUvs[ 0 ],\n\t\t\tuvs2 = geometry.faceVertexUvs[ 0 ],\n\t\t\tcolors1 = this.colors,\n\t\t\tcolors2 = geometry.colors;\n\n\t\t\tif ( materialIndexOffset === undefined ) materialIndexOffset = 0;\n\n\t\t\tif ( matrix !== undefined ) {\n\n\t\t\t\tnormalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t}\n\n\t\t\t// vertices\n\n\t\t\tfor ( var i = 0, il = vertices2.length; i < il; i ++ ) {\n\n\t\t\t\tvar vertex = vertices2[ i ];\n\n\t\t\t\tvar vertexCopy = vertex.clone();\n\n\t\t\t\tif ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );\n\n\t\t\t\tvertices1.push( vertexCopy );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tfor ( var i = 0, il = colors2.length; i < il; i ++ ) {\n\n\t\t\t\tcolors1.push( colors2[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tfor ( i = 0, il = faces2.length; i < il; i ++ ) {\n\n\t\t\t\tvar face = faces2[ i ], faceCopy, normal, color,\n\t\t\t\tfaceVertexNormals = face.vertexNormals,\n\t\t\t\tfaceVertexColors = face.vertexColors;\n\n\t\t\t\tfaceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );\n\t\t\t\tfaceCopy.normal.copy( face.normal );\n\n\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\tfaceCopy.normal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\tnormal = faceVertexNormals[ j ].clone();\n\n\t\t\t\t\tif ( normalMatrix !== undefined ) {\n\n\t\t\t\t\t\tnormal.applyMatrix3( normalMatrix ).normalize();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfaceCopy.vertexNormals.push( normal );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.color.copy( face.color );\n\n\t\t\t\tfor ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {\n\n\t\t\t\t\tcolor = faceVertexColors[ j ];\n\t\t\t\t\tfaceCopy.vertexColors.push( color.clone() );\n\n\t\t\t\t}\n\n\t\t\t\tfaceCopy.materialIndex = face.materialIndex + materialIndexOffset;\n\n\t\t\t\tfaces1.push( faceCopy );\n\n\t\t\t}\n\n\t\t\t// uvs\n\n\t\t\tfor ( i = 0, il = uvs2.length; i < il; i ++ ) {\n\n\t\t\t\tvar uv = uvs2[ i ], uvCopy = [];\n\n\t\t\t\tif ( uv === undefined ) {\n\n\t\t\t\t\tcontinue;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var j = 0, jl = uv.length; j < jl; j ++ ) {\n\n\t\t\t\t\tuvCopy.push( uv[ j ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tuvs1.push( uvCopy );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmergeMesh: function ( mesh ) {\n\n\t\t\tif ( ( mesh && mesh.isMesh ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tmesh.matrixAutoUpdate && mesh.updateMatrix();\n\n\t\t\tthis.merge( mesh.geometry, mesh.matrix );\n\n\t\t},\n\n\t\t/*\n\t\t * Checks for duplicate vertices with hashmap.\n\t\t * Duplicated vertices are removed\n\t\t * and faces' vertices are updated.\n\t\t */\n\n\t\tmergeVertices: function () {\n\n\t\t\tvar verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)\n\t\t\tvar unique = [], changes = [];\n\n\t\t\tvar v, key;\n\t\t\tvar precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001\n\t\t\tvar precision = Math.pow( 10, precisionPoints );\n\t\t\tvar i, il, face;\n\t\t\tvar indices, j, jl;\n\n\t\t\tfor ( i = 0, il = this.vertices.length; i < il; i ++ ) {\n\n\t\t\t\tv = this.vertices[ i ];\n\t\t\t\tkey = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );\n\n\t\t\t\tif ( verticesMap[ key ] === undefined ) {\n\n\t\t\t\t\tverticesMap[ key ] = i;\n\t\t\t\t\tunique.push( this.vertices[ i ] );\n\t\t\t\t\tchanges[ i ] = unique.length - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);\n\t\t\t\t\tchanges[ i ] = changes[ verticesMap[ key ] ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\t// if faces are completely degenerate after merging vertices, we\n\t\t\t// have to remove them from the geometry.\n\t\t\tvar faceIndicesToRemove = [];\n\n\t\t\tfor ( i = 0, il = this.faces.length; i < il; i ++ ) {\n\n\t\t\t\tface = this.faces[ i ];\n\n\t\t\t\tface.a = changes[ face.a ];\n\t\t\t\tface.b = changes[ face.b ];\n\t\t\t\tface.c = changes[ face.c ];\n\n\t\t\t\tindices = [ face.a, face.b, face.c ];\n\n\t\t\t\t// if any duplicate vertices are found in a Face3\n\t\t\t\t// we have to remove the face as nothing can be saved\n\t\t\t\tfor ( var n = 0; n < 3; n ++ ) {\n\n\t\t\t\t\tif ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {\n\n\t\t\t\t\t\tfaceIndicesToRemove.push( i );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {\n\n\t\t\t\tvar idx = faceIndicesToRemove[ i ];\n\n\t\t\t\tthis.faces.splice( idx, 1 );\n\n\t\t\t\tfor ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ j ].splice( idx, 1 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Use unique set of vertices\n\n\t\t\tvar diff = this.vertices.length - unique.length;\n\t\t\tthis.vertices = unique;\n\t\t\treturn diff;\n\n\t\t},\n\n\t\tsortFacesByMaterialIndex: function () {\n\n\t\t\tvar faces = this.faces;\n\t\t\tvar length = faces.length;\n\n\t\t\t// tag faces\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tfaces[ i ]._id = i;\n\n\t\t\t}\n\n\t\t\t// sort faces\n\n\t\t\tfunction materialIndexSort( a, b ) {\n\n\t\t\t\treturn a.materialIndex - b.materialIndex;\n\n\t\t\t}\n\n\t\t\tfaces.sort( materialIndexSort );\n\n\t\t\t// sort uvs\n\n\t\t\tvar uvs1 = this.faceVertexUvs[ 0 ];\n\t\t\tvar uvs2 = this.faceVertexUvs[ 1 ];\n\n\t\t\tvar newUvs1, newUvs2;\n\n\t\t\tif ( uvs1 && uvs1.length === length ) newUvs1 = [];\n\t\t\tif ( uvs2 && uvs2.length === length ) newUvs2 = [];\n\n\t\t\tfor ( var i = 0; i < length; i ++ ) {\n\n\t\t\t\tvar id = faces[ i ]._id;\n\n\t\t\t\tif ( newUvs1 ) newUvs1.push( uvs1[ id ] );\n\t\t\t\tif ( newUvs2 ) newUvs2.push( uvs2[ id ] );\n\n\t\t\t}\n\n\t\t\tif ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;\n\t\t\tif ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'Geometry',\n\t\t\t\t\tgenerator: 'Geometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard Geometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tvar vertices = [];\n\n\t\t\tfor ( var i = 0; i < this.vertices.length; i ++ ) {\n\n\t\t\t\tvar vertex = this.vertices[ i ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t\tvar faces = [];\n\t\t\tvar normals = [];\n\t\t\tvar normalsHash = {};\n\t\t\tvar colors = [];\n\t\t\tvar colorsHash = {};\n\t\t\tvar uvs = [];\n\t\t\tvar uvsHash = {};\n\n\t\t\tfor ( var i = 0; i < this.faces.length; i ++ ) {\n\n\t\t\t\tvar face = this.faces[ i ];\n\n\t\t\t\tvar hasMaterial = true;\n\t\t\t\tvar hasFaceUv = false; // deprecated\n\t\t\t\tvar hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;\n\t\t\t\tvar hasFaceNormal = face.normal.length() > 0;\n\t\t\t\tvar hasFaceVertexNormal = face.vertexNormals.length > 0;\n\t\t\t\tvar hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;\n\t\t\t\tvar hasFaceVertexColor = face.vertexColors.length > 0;\n\n\t\t\t\tvar faceType = 0;\n\n\t\t\t\tfaceType = setBit( faceType, 0, 0 ); // isQuad\n\t\t\t\tfaceType = setBit( faceType, 1, hasMaterial );\n\t\t\t\tfaceType = setBit( faceType, 2, hasFaceUv );\n\t\t\t\tfaceType = setBit( faceType, 3, hasFaceVertexUv );\n\t\t\t\tfaceType = setBit( faceType, 4, hasFaceNormal );\n\t\t\t\tfaceType = setBit( faceType, 5, hasFaceVertexNormal );\n\t\t\t\tfaceType = setBit( faceType, 6, hasFaceColor );\n\t\t\t\tfaceType = setBit( faceType, 7, hasFaceVertexColor );\n\n\t\t\t\tfaces.push( faceType );\n\t\t\t\tfaces.push( face.a, face.b, face.c );\n\t\t\t\tfaces.push( face.materialIndex );\n\n\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\tvar faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 0 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 1 ] ),\n\t\t\t\t\t\tgetUvIndex( faceVertexUvs[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\tfaces.push( getNormalIndex( face.normal ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\tvar vertexNormals = face.vertexNormals;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 0 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 1 ] ),\n\t\t\t\t\t\tgetNormalIndex( vertexNormals[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\tfaces.push( getColorIndex( face.color ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\tvar vertexColors = face.vertexColors;\n\n\t\t\t\t\tfaces.push(\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 0 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 1 ] ),\n\t\t\t\t\t\tgetColorIndex( vertexColors[ 2 ] )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction setBit( value, position, enabled ) {\n\n\t\t\t\treturn enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );\n\n\t\t\t}\n\n\t\t\tfunction getNormalIndex( normal ) {\n\n\t\t\t\tvar hash = normal.x.toString() + normal.y.toString() + normal.z.toString();\n\n\t\t\t\tif ( normalsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tnormalsHash[ hash ] = normals.length / 3;\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\treturn normalsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getColorIndex( color ) {\n\n\t\t\t\tvar hash = color.r.toString() + color.g.toString() + color.b.toString();\n\n\t\t\t\tif ( colorsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tcolorsHash[ hash ] = colors.length;\n\t\t\t\tcolors.push( color.getHex() );\n\n\t\t\t\treturn colorsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tfunction getUvIndex( uv ) {\n\n\t\t\t\tvar hash = uv.x.toString() + uv.y.toString();\n\n\t\t\t\tif ( uvsHash[ hash ] !== undefined ) {\n\n\t\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t\t}\n\n\t\t\t\tuvsHash[ hash ] = uvs.length / 2;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\treturn uvsHash[ hash ];\n\n\t\t\t}\n\n\t\t\tdata.data = {};\n\n\t\t\tdata.data.vertices = vertices;\n\t\t\tdata.data.normals = normals;\n\t\t\tif ( colors.length > 0 ) data.data.colors = colors;\n\t\t\tif ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility\n\t\t\tdata.data.faces = faces;\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new Geometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar i, il, j, jl, k, kl;\n\n\t\t\t// reset\n\n\t\t\tthis.vertices = [];\n\t\t\tthis.colors = [];\n\t\t\tthis.faces = [];\n\t\t\tthis.faceVertexUvs = [[]];\n\t\t\tthis.morphTargets = [];\n\t\t\tthis.morphNormals = [];\n\t\t\tthis.skinWeights = [];\n\t\t\tthis.skinIndices = [];\n\t\t\tthis.lineDistances = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// vertices\n\n\t\t\tvar vertices = source.vertices;\n\n\t\t\tfor ( i = 0, il = vertices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.vertices.push( vertices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// colors\n\n\t\t\tvar colors = source.colors;\n\n\t\t\tfor ( i = 0, il = colors.length; i < il; i ++ ) {\n\n\t\t\t\tthis.colors.push( colors[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// faces\n\n\t\t\tvar faces = source.faces;\n\n\t\t\tfor ( i = 0, il = faces.length; i < il; i ++ ) {\n\n\t\t\t\tthis.faces.push( faces[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// face vertex uvs\n\n\t\t\tfor ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {\n\n\t\t\t\tvar faceVertexUvs = source.faceVertexUvs[ i ];\n\n\t\t\t\tif ( this.faceVertexUvs[ i ] === undefined ) {\n\n\t\t\t\t\tthis.faceVertexUvs[ i ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {\n\n\t\t\t\t\tvar uvs = faceVertexUvs[ j ], uvsCopy = [];\n\n\t\t\t\t\tfor ( k = 0, kl = uvs.length; k < kl; k ++ ) {\n\n\t\t\t\t\t\tvar uv = uvs[ k ];\n\n\t\t\t\t\t\tuvsCopy.push( uv.clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.faceVertexUvs[ i ].push( uvsCopy );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargets = source.morphTargets;\n\n\t\t\tfor ( i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = {};\n\t\t\t\tmorphTarget.name = morphTargets[ i ].name;\n\n\t\t\t\t// vertices\n\n\t\t\t\tif ( morphTargets[ i ].vertices !== undefined ) {\n\n\t\t\t\t\tmorphTarget.vertices = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// normals\n\n\t\t\t\tif ( morphTargets[ i ].normals !== undefined ) {\n\n\t\t\t\t\tmorphTarget.normals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphTargets.push( morphTarget );\n\n\t\t\t}\n\n\t\t\t// morph normals\n\n\t\t\tvar morphNormals = source.morphNormals;\n\n\t\t\tfor ( i = 0, il = morphNormals.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphNormal = {};\n\n\t\t\t\t// vertex normals\n\n\t\t\t\tif ( morphNormals[ i ].vertexNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.vertexNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];\n\t\t\t\t\t\tvar destVertexNormal = {};\n\n\t\t\t\t\t\tdestVertexNormal.a = srcVertexNormal.a.clone();\n\t\t\t\t\t\tdestVertexNormal.b = srcVertexNormal.b.clone();\n\t\t\t\t\t\tdestVertexNormal.c = srcVertexNormal.c.clone();\n\n\t\t\t\t\t\tmorphNormal.vertexNormals.push( destVertexNormal );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// face normals\n\n\t\t\t\tif ( morphNormals[ i ].faceNormals !== undefined ) {\n\n\t\t\t\t\tmorphNormal.faceNormals = [];\n\n\t\t\t\t\tfor ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tmorphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphNormals.push( morphNormal );\n\n\t\t\t}\n\n\t\t\t// skin weights\n\n\t\t\tvar skinWeights = source.skinWeights;\n\n\t\t\tfor ( i = 0, il = skinWeights.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinWeights.push( skinWeights[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// skin indices\n\n\t\t\tvar skinIndices = source.skinIndices;\n\n\t\t\tfor ( i = 0, il = skinIndices.length; i < il; i ++ ) {\n\n\t\t\t\tthis.skinIndices.push( skinIndices[ i ].clone() );\n\n\t\t\t}\n\n\t\t\t// line distances\n\n\t\t\tvar lineDistances = source.lineDistances;\n\n\t\t\tfor ( i = 0, il = lineDistances.length; i < il; i ++ ) {\n\n\t\t\t\tthis.lineDistances.push( lineDistances[ i ] );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// update flags\n\n\t\t\tthis.elementsNeedUpdate = source.elementsNeedUpdate;\n\t\t\tthis.verticesNeedUpdate = source.verticesNeedUpdate;\n\t\t\tthis.uvsNeedUpdate = source.uvsNeedUpdate;\n\t\t\tthis.normalsNeedUpdate = source.normalsNeedUpdate;\n\t\t\tthis.colorsNeedUpdate = source.colorsNeedUpdate;\n\t\t\tthis.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;\n\t\t\tthis.groupsNeedUpdate = source.groupsNeedUpdate;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tObject.assign( Geometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometry() {\n\n\t\tObject.defineProperty( this, 'id', { value: GeometryIdCount() } );\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.name = '';\n\t\tthis.type = 'BufferGeometry';\n\n\t\tthis.index = null;\n\t\tthis.attributes = {};\n\n\t\tthis.morphAttributes = {};\n\n\t\tthis.groups = [];\n\n\t\tthis.boundingBox = null;\n\t\tthis.boundingSphere = null;\n\n\t\tthis.drawRange = { start: 0, count: Infinity };\n\n\t}\n\n\tBufferGeometry.prototype = {\n\n\t\tconstructor: BufferGeometry,\n\n\t\tisBufferGeometry: true,\n\n\t\tgetIndex: function () {\n\n\t\t\treturn this.index;\n\n\t\t},\n\n\t\tsetIndex: function ( index ) {\n\n\t\t\tif ( Array.isArray( index ) ) {\n\n\t\t\t\tthis.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );\n\n\t\t\t} else {\n\n\t\t\t\tthis.index = index;\n\n\t\t\t}\n\n\t\t},\n\n\t\taddAttribute: function ( name, attribute ) {\n\n\t\t\tif ( ( attribute && attribute.isBufferAttribute ) === false && ( attribute && attribute.isInterleavedBufferAttribute ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );\n\n\t\t\t\tthis.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( name === 'index' ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );\n\t\t\t\tthis.setIndex( attribute );\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.attributes[ name ] = attribute;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetAttribute: function ( name ) {\n\n\t\t\treturn this.attributes[ name ];\n\n\t\t},\n\n\t\tremoveAttribute: function ( name ) {\n\n\t\t\tdelete this.attributes[ name ];\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddGroup: function ( start, count, materialIndex ) {\n\n\t\t\tthis.groups.push( {\n\n\t\t\t\tstart: start,\n\t\t\t\tcount: count,\n\t\t\t\tmaterialIndex: materialIndex !== undefined ? materialIndex : 0\n\n\t\t\t} );\n\n\t\t},\n\n\t\tclearGroups: function () {\n\n\t\t\tthis.groups = [];\n\n\t\t},\n\n\t\tsetDrawRange: function ( start, count ) {\n\n\t\t\tthis.drawRange.start = start;\n\t\t\tthis.drawRange.count = count;\n\n\t\t},\n\n\t\tapplyMatrix: function ( matrix ) {\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tmatrix.applyToBufferAttribute( position );\n\t\t\t\tposition.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tvar normal = this.attributes.normal;\n\n\t\t\tif ( normal !== undefined ) {\n\n\t\t\t\tvar normalMatrix = new Matrix3().getNormalMatrix( matrix );\n\n\t\t\t\tnormalMatrix.applyToBufferAttribute( normal );\n\t\t\t\tnormal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tif ( this.boundingBox !== null ) {\n\n\t\t\t\tthis.computeBoundingBox();\n\n\t\t\t}\n\n\t\t\tif ( this.boundingSphere !== null ) {\n\n\t\t\t\tthis.computeBoundingSphere();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\trotateX: function () {\n\n\t\t\t// rotate geometry around world x-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateX( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationX( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateY: function () {\n\n\t\t\t// rotate geometry around world y-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateY( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationY( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\trotateZ: function () {\n\n\t\t\t// rotate geometry around world z-axis\n\n\t\t\tvar m1;\n\n\t\t\treturn function rotateZ( angle ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeRotationZ( angle );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttranslate: function () {\n\n\t\t\t// translate geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function translate( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeTranslation( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tscale: function () {\n\n\t\t\t// scale geometry\n\n\t\t\tvar m1;\n\n\t\t\treturn function scale( x, y, z ) {\n\n\t\t\t\tif ( m1 === undefined ) m1 = new Matrix4();\n\n\t\t\t\tm1.makeScale( x, y, z );\n\n\t\t\t\tthis.applyMatrix( m1 );\n\n\t\t\t\treturn this;\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tlookAt: function () {\n\n\t\t\tvar obj;\n\n\t\t\treturn function lookAt( vector ) {\n\n\t\t\t\tif ( obj === undefined ) obj = new Object3D();\n\n\t\t\t\tobj.lookAt( vector );\n\n\t\t\t\tobj.updateMatrix();\n\n\t\t\t\tthis.applyMatrix( obj.matrix );\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcenter: function () {\n\n\t\t\tthis.computeBoundingBox();\n\n\t\t\tvar offset = this.boundingBox.getCenter().negate();\n\n\t\t\tthis.translate( offset.x, offset.y, offset.z );\n\n\t\t\treturn offset;\n\n\t\t},\n\n\t\tsetFromObject: function ( object ) {\n\n\t\t\t// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isPoints || object.isLine ) {\n\n\t\t\t\tvar positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );\n\t\t\t\tvar colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );\n\n\t\t\t\tthis.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );\n\t\t\t\tthis.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );\n\n\t\t\t\tif ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {\n\n\t\t\t\t\tvar lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );\n\n\t\t\t\t\tthis.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isMesh ) {\n\n\t\t\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t\t\tthis.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateFromObject: function ( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tvar direct = geometry.__directGeometry;\n\n\t\t\t\tif ( geometry.elementsNeedUpdate === true ) {\n\n\t\t\t\t\tdirect = undefined;\n\t\t\t\t\tgeometry.elementsNeedUpdate = false;\n\n\t\t\t\t}\n\n\t\t\t\tif ( direct === undefined ) {\n\n\t\t\t\t\treturn this.fromGeometry( geometry );\n\n\t\t\t\t}\n\n\t\t\t\tdirect.verticesNeedUpdate = geometry.verticesNeedUpdate;\n\t\t\t\tdirect.normalsNeedUpdate = geometry.normalsNeedUpdate;\n\t\t\t\tdirect.colorsNeedUpdate = geometry.colorsNeedUpdate;\n\t\t\t\tdirect.uvsNeedUpdate = geometry.uvsNeedUpdate;\n\t\t\t\tdirect.groupsNeedUpdate = geometry.groupsNeedUpdate;\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t\tgeometry = direct;\n\n\t\t\t}\n\n\t\t\tvar attribute;\n\n\t\t\tif ( geometry.verticesNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.position;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.vertices );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.verticesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.normalsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.normal;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector3sArray( geometry.normals );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.normalsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.colorsNeedUpdate === true ) {\n\n\t\t\t\tattribute = this.attributes.color;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyColorsArray( geometry.colors );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.colorsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvsNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.uv;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyVector2sArray( geometry.uvs );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.uvsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.lineDistancesNeedUpdate ) {\n\n\t\t\t\tattribute = this.attributes.lineDistance;\n\n\t\t\t\tif ( attribute !== undefined ) {\n\n\t\t\t\t\tattribute.copyArray( geometry.lineDistances );\n\t\t\t\t\tattribute.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.lineDistancesNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\tif ( geometry.groupsNeedUpdate ) {\n\n\t\t\t\tgeometry.computeGroups( object.geometry );\n\t\t\t\tthis.groups = geometry.groups;\n\n\t\t\t\tgeometry.groupsNeedUpdate = false;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tfromGeometry: function ( geometry ) {\n\n\t\t\tgeometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );\n\n\t\t\treturn this.fromDirectGeometry( geometry.__directGeometry );\n\n\t\t},\n\n\t\tfromDirectGeometry: function ( geometry ) {\n\n\t\t\tvar positions = new Float32Array( geometry.vertices.length * 3 );\n\t\t\tthis.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );\n\n\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\tvar normals = new Float32Array( geometry.normals.length * 3 );\n\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\tvar colors = new Float32Array( geometry.colors.length * 3 );\n\t\t\t\tthis.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs.length > 0 ) {\n\n\t\t\t\tvar uvs = new Float32Array( geometry.uvs.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.uvs2.length > 0 ) {\n\n\t\t\t\tvar uvs2 = new Float32Array( geometry.uvs2.length * 2 );\n\t\t\t\tthis.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.indices.length > 0 ) {\n\n\t\t\t\tvar TypeArray = arrayMax( geometry.indices ) > 65535 ? Uint32Array : Uint16Array;\n\t\t\t\tvar indices = new TypeArray( geometry.indices.length * 3 );\n\t\t\t\tthis.setIndex( new BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tthis.groups = geometry.groups;\n\n\t\t\t// morphs\n\n\t\t\tfor ( var name in geometry.morphTargets ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphTargets = geometry.morphTargets[ name ];\n\n\t\t\t\tfor ( var i = 0, l = morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar morphTarget = morphTargets[ i ];\n\n\t\t\t\t\tvar attribute = new Float32BufferAttribute( morphTarget.length * 3, 3 );\n\n\t\t\t\t\tarray.push( attribute.copyVector3sArray( morphTarget ) );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// skinning\n\n\t\t\tif ( geometry.skinIndices.length > 0 ) {\n\n\t\t\t\tvar skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );\n\n\t\t\t}\n\n\t\t\tif ( geometry.skinWeights.length > 0 ) {\n\n\t\t\t\tvar skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );\n\t\t\t\tthis.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( geometry.boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = geometry.boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = geometry.boundingBox.clone();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcomputeBoundingBox: function () {\n\n\t\t\tif ( this.boundingBox === null ) {\n\n\t\t\t\tthis.boundingBox = new Box3();\n\n\t\t\t}\n\n\t\t\tvar position = this.attributes.position;\n\n\t\t\tif ( position !== undefined ) {\n\n\t\t\t\tthis.boundingBox.setFromBufferAttribute( position );\n\n\t\t\t} else {\n\n\t\t\t\tthis.boundingBox.makeEmpty();\n\n\t\t\t}\n\n\t\t\tif ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t}\n\n\t\t},\n\n\t\tcomputeBoundingSphere: function () {\n\n\t\t\tvar box = new Box3();\n\t\t\tvar vector = new Vector3();\n\n\t\t\treturn function computeBoundingSphere() {\n\n\t\t\t\tif ( this.boundingSphere === null ) {\n\n\t\t\t\t\tthis.boundingSphere = new Sphere();\n\n\t\t\t\t}\n\n\t\t\t\tvar position = this.attributes.position;\n\n\t\t\t\tif ( position ) {\n\n\t\t\t\t\tvar center = this.boundingSphere.center;\n\n\t\t\t\t\tbox.setFromBufferAttribute( position );\n\t\t\t\t\tbox.getCenter( center );\n\n\t\t\t\t\t// hoping to find a boundingSphere with a radius smaller than the\n\t\t\t\t\t// boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t\t\t\tvar maxRadiusSq = 0;\n\n\t\t\t\t\tfor ( var i = 0, il = position.count; i < il; i ++ ) {\n\n\t\t\t\t\t\tvector.x = position.getX( i );\n\t\t\t\t\t\tvector.y = position.getY( i );\n\t\t\t\t\t\tvector.z = position.getZ( i );\n\t\t\t\t\t\tmaxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.boundingSphere.radius = Math.sqrt( maxRadiusSq );\n\n\t\t\t\t\tif ( isNaN( this.boundingSphere.radius ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.', this );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\tcomputeFaceNormals: function () {\n\n\t\t\t// backwards compatibility\n\n\t\t},\n\n\t\tcomputeVertexNormals: function () {\n\n\t\t\tvar index = this.index;\n\t\t\tvar attributes = this.attributes;\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( attributes.position ) {\n\n\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\tif ( attributes.normal === undefined ) {\n\n\t\t\t\t\tthis.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// reset existing normals to zero\n\n\t\t\t\t\tvar array = attributes.normal.array;\n\n\t\t\t\t\tfor ( var i = 0, il = array.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tarray[ i ] = 0;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar normals = attributes.normal.array;\n\n\t\t\t\tvar vA, vB, vC;\n\t\t\t\tvar pA = new Vector3(), pB = new Vector3(), pC = new Vector3();\n\t\t\t\tvar cb = new Vector3(), ab = new Vector3();\n\n\t\t\t\t// indexed elements\n\n\t\t\t\tif ( index ) {\n\n\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\t\tthis.addGroup( 0, indices.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var j = 0, jl = groups.length; j < jl; ++ j ) {\n\n\t\t\t\t\t\tvar group = groups[ j ];\n\n\t\t\t\t\t\tvar start = group.start;\n\t\t\t\t\t\tvar count = group.count;\n\n\t\t\t\t\t\tfor ( var i = start, il = start + count; i < il; i += 3 ) {\n\n\t\t\t\t\t\t\tvA = indices[ i + 0 ] * 3;\n\t\t\t\t\t\t\tvB = indices[ i + 1 ] * 3;\n\t\t\t\t\t\t\tvC = indices[ i + 2 ] * 3;\n\n\t\t\t\t\t\t\tpA.fromArray( positions, vA );\n\t\t\t\t\t\t\tpB.fromArray( positions, vB );\n\t\t\t\t\t\t\tpC.fromArray( positions, vC );\n\n\t\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\t\tnormals[ vA ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vA + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vA + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vB ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vB + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vB + 2 ] += cb.z;\n\n\t\t\t\t\t\t\tnormals[ vC ] += cb.x;\n\t\t\t\t\t\t\tnormals[ vC + 1 ] += cb.y;\n\t\t\t\t\t\t\tnormals[ vC + 2 ] += cb.z;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// non-indexed elements (unconnected triangle soup)\n\n\t\t\t\t\tfor ( var i = 0, il = positions.length; i < il; i += 9 ) {\n\n\t\t\t\t\t\tpA.fromArray( positions, i );\n\t\t\t\t\t\tpB.fromArray( positions, i + 3 );\n\t\t\t\t\t\tpC.fromArray( positions, i + 6 );\n\n\t\t\t\t\t\tcb.subVectors( pC, pB );\n\t\t\t\t\t\tab.subVectors( pA, pB );\n\t\t\t\t\t\tcb.cross( ab );\n\n\t\t\t\t\t\tnormals[ i ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 1 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 2 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 3 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 4 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 5 ] = cb.z;\n\n\t\t\t\t\t\tnormals[ i + 6 ] = cb.x;\n\t\t\t\t\t\tnormals[ i + 7 ] = cb.y;\n\t\t\t\t\t\tnormals[ i + 8 ] = cb.z;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis.normalizeNormals();\n\n\t\t\t\tattributes.normal.needsUpdate = true;\n\n\t\t\t}\n\n\t\t},\n\n\t\tmerge: function ( geometry, offset ) {\n\n\t\t\tif ( ( geometry && geometry.isBufferGeometry ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tif ( geometry.attributes[ key ] === undefined ) continue;\n\n\t\t\t\tvar attribute1 = attributes[ key ];\n\t\t\t\tvar attributeArray1 = attribute1.array;\n\n\t\t\t\tvar attribute2 = geometry.attributes[ key ];\n\t\t\t\tvar attributeArray2 = attribute2.array;\n\n\t\t\t\tvar attributeSize = attribute2.itemSize;\n\n\t\t\t\tfor ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {\n\n\t\t\t\t\tattributeArray1[ j ] = attributeArray2[ i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tnormalizeNormals: function () {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\n\t\t\tvar x, y, z, n;\n\n\t\t\tfor ( var i = 0, il = normals.length; i < il; i += 3 ) {\n\n\t\t\t\tx = normals[ i ];\n\t\t\t\ty = normals[ i + 1 ];\n\t\t\t\tz = normals[ i + 2 ];\n\n\t\t\t\tn = 1.0 / Math.sqrt( x * x + y * y + z * z );\n\n\t\t\t\tnormals[ i ] *= n;\n\t\t\t\tnormals[ i + 1 ] *= n;\n\t\t\t\tnormals[ i + 2 ] *= n;\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoNonIndexed: function () {\n\n\t\t\tif ( this.index === null ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\n\t\t\tvar geometry2 = new BufferGeometry();\n\n\t\t\tvar indices = this.index.array;\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\n\t\t\t\tvar array = attribute.array;\n\t\t\t\tvar itemSize = attribute.itemSize;\n\n\t\t\t\tvar array2 = new array.constructor( indices.length * itemSize );\n\n\t\t\t\tvar index = 0, index2 = 0;\n\n\t\t\t\tfor ( var i = 0, l = indices.length; i < l; i ++ ) {\n\n\t\t\t\t\tindex = indices[ i ] * itemSize;\n\n\t\t\t\t\tfor ( var j = 0; j < itemSize; j ++ ) {\n\n\t\t\t\t\t\tarray2[ index2 ++ ] = array[ index ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry2.addAttribute( name, new BufferAttribute( array2, itemSize ) );\n\n\t\t\t}\n\n\t\t\treturn geometry2;\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar data = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.4,\n\t\t\t\t\ttype: 'BufferGeometry',\n\t\t\t\t\tgenerator: 'BufferGeometry.toJSON'\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// standard BufferGeometry serialization\n\n\t\t\tdata.uuid = this.uuid;\n\t\t\tdata.type = this.type;\n\t\t\tif ( this.name !== '' ) data.name = this.name;\n\n\t\t\tif ( this.parameters !== undefined ) {\n\n\t\t\t\tvar parameters = this.parameters;\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tif ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];\n\n\t\t\t\t}\n\n\t\t\t\treturn data;\n\n\t\t\t}\n\n\t\t\tdata.data = { attributes: {} };\n\n\t\t\tvar index = this.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = Array.prototype.slice.call( index.array );\n\n\t\t\t\tdata.data.index = {\n\t\t\t\t\ttype: index.array.constructor.name,\n\t\t\t\t\tarray: array\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar attributes = this.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\n\t\t\t\tvar array = Array.prototype.slice.call( attribute.array );\n\n\t\t\t\tdata.data.attributes[ key ] = {\n\t\t\t\t\titemSize: attribute.itemSize,\n\t\t\t\t\ttype: attribute.array.constructor.name,\n\t\t\t\t\tarray: array,\n\t\t\t\t\tnormalized: attribute.normalized\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tvar groups = this.groups;\n\n\t\t\tif ( groups.length > 0 ) {\n\n\t\t\t\tdata.data.groups = JSON.parse( JSON.stringify( groups ) );\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = this.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tdata.data.boundingSphere = {\n\t\t\t\t\tcenter: boundingSphere.center.toArray(),\n\t\t\t\t\tradius: boundingSphere.radius\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\t/*\n\t\t\t// Handle primitives\n\n\t\t\tvar parameters = this.parameters;\n\n\t\t\tif ( parameters !== undefined ) {\n\n\t\t\t\tvar values = [];\n\n\t\t\t\tfor ( var key in parameters ) {\n\n\t\t\t\t\tvalues.push( parameters[ key ] );\n\n\t\t\t\t}\n\n\t\t\t\tvar geometry = Object.create( this.constructor.prototype );\n\t\t\t\tthis.constructor.apply( geometry, values );\n\t\t\t\treturn geometry;\n\n\t\t\t}\n\n\t\t\treturn new this.constructor().copy( this );\n\t\t\t*/\n\n\t\t\treturn new BufferGeometry().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tvar name, i, l;\n\n\t\t\t// reset\n\n\t\t\tthis.index = null;\n\t\t\tthis.attributes = {};\n\t\t\tthis.morphAttributes = {};\n\t\t\tthis.groups = [];\n\t\t\tthis.boundingBox = null;\n\t\t\tthis.boundingSphere = null;\n\n\t\t\t// name\n\n\t\t\tthis.name = source.name;\n\n\t\t\t// index\n\n\t\t\tvar index = source.index;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tthis.setIndex( index.clone() );\n\n\t\t\t}\n\n\t\t\t// attributes\n\n\t\t\tvar attributes = source.attributes;\n\n\t\t\tfor ( name in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ name ];\n\t\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t\t}\n\n\t\t\t// morph attributes\n\n\t\t\tvar morphAttributes = source.morphAttributes;\n\n\t\t\tfor ( name in morphAttributes ) {\n\n\t\t\t\tvar array = [];\n\t\t\t\tvar morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes\n\n\t\t\t\tfor ( i = 0, l = morphAttribute.length; i < l; i ++ ) {\n\n\t\t\t\t\tarray.push( morphAttribute[ i ].clone() );\n\n\t\t\t\t}\n\n\t\t\t\tthis.morphAttributes[ name ] = array;\n\n\t\t\t}\n\n\t\t\t// groups\n\n\t\t\tvar groups = source.groups;\n\n\t\t\tfor ( i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\tvar group = groups[ i ];\n\t\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t}\n\n\t\t\t// bounding box\n\n\t\t\tvar boundingBox = source.boundingBox;\n\n\t\t\tif ( boundingBox !== null ) {\n\n\t\t\t\tthis.boundingBox = boundingBox.clone();\n\n\t\t\t}\n\n\t\t\t// bounding sphere\n\n\t\t\tvar boundingSphere = source.boundingSphere;\n\n\t\t\tif ( boundingSphere !== null ) {\n\n\t\t\t\tthis.boundingSphere = boundingSphere.clone();\n\n\t\t\t}\n\n\t\t\t// draw range\n\n\t\t\tthis.drawRange.start = source.drawRange.start;\n\t\t\tthis.drawRange.count = source.drawRange.count;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdispose: function () {\n\n\t\t\tthis.dispatchEvent( { type: 'dispose' } );\n\n\t\t}\n\n\t};\n\n\tBufferGeometry.MaxIndex = 65535;\n\n\tObject.assign( BufferGeometry.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author jonobr1 / http://jonobr1.com/\n\t */\n\n\tfunction Mesh( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Mesh';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t\tthis.drawMode = TrianglesDrawMode;\n\n\t\tthis.updateMorphTargets();\n\n\t}\n\n\tMesh.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Mesh,\n\n\t\tisMesh: true,\n\n\t\tsetDrawMode: function ( value ) {\n\n\t\t\tthis.drawMode = value;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.drawMode = source.drawMode;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tupdateMorphTargets: function () {\n\n\t\t\tvar morphTargets = this.geometry.morphTargets;\n\n\t\t\tif ( morphTargets !== undefined && morphTargets.length > 0 ) {\n\n\t\t\t\tthis.morphTargetInfluences = [];\n\t\t\t\tthis.morphTargetDictionary = {};\n\n\t\t\t\tfor ( var m = 0, ml = morphTargets.length; m < ml; m ++ ) {\n\n\t\t\t\t\tthis.morphTargetInfluences.push( 0 );\n\t\t\t\t\tthis.morphTargetDictionary[ morphTargets[ m ].name ] = m;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\tvar vA = new Vector3();\n\t\t\tvar vB = new Vector3();\n\t\t\tvar vC = new Vector3();\n\n\t\t\tvar tempA = new Vector3();\n\t\t\tvar tempB = new Vector3();\n\t\t\tvar tempC = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tvar barycoord = new Vector3();\n\n\t\t\tvar intersectionPoint = new Vector3();\n\t\t\tvar intersectionPointWorld = new Vector3();\n\n\t\t\tfunction uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {\n\n\t\t\t\tTriangle.barycoordFromPoint( point, p1, p2, p3, barycoord );\n\n\t\t\t\tuv1.multiplyScalar( barycoord.x );\n\t\t\t\tuv2.multiplyScalar( barycoord.y );\n\t\t\t\tuv3.multiplyScalar( barycoord.z );\n\n\t\t\t\tuv1.add( uv2 ).add( uv3 );\n\n\t\t\t\treturn uv1.clone();\n\n\t\t\t}\n\n\t\t\tfunction checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {\n\n\t\t\t\tvar intersect;\n\t\t\t\tvar material = object.material;\n\n\t\t\t\tif ( material.side === BackSide ) {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pC, pB, pA, true, point );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tintersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );\n\n\t\t\t\t}\n\n\t\t\t\tif ( intersect === null ) return null;\n\n\t\t\t\tintersectionPointWorld.copy( point );\n\t\t\t\tintersectionPointWorld.applyMatrix4( object.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectionPointWorld );\n\n\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return null;\n\n\t\t\t\treturn {\n\t\t\t\t\tdistance: distance,\n\t\t\t\t\tpoint: intersectionPointWorld.clone(),\n\t\t\t\t\tobject: object\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\tfunction checkBufferGeometryIntersection( object, raycaster, ray, position, uv, a, b, c ) {\n\n\t\t\t\tvA.fromBufferAttribute( position, a );\n\t\t\t\tvB.fromBufferAttribute( position, b );\n\t\t\t\tvC.fromBufferAttribute( position, c );\n\n\t\t\t\tvar intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );\n\n\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\tif ( uv ) {\n\n\t\t\t\t\t\tuvA.fromBufferAttribute( uv, a );\n\t\t\t\t\t\tuvB.fromBufferAttribute( uv, b );\n\t\t\t\t\t\tuvC.fromBufferAttribute( uv, c );\n\n\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tintersection.face = new Face3( a, b, c, Triangle.normal( vA, vB, vC ) );\n\t\t\t\t\tintersection.faceIndex = a;\n\n\t\t\t\t}\n\n\t\t\t\treturn intersection;\n\n\t\t\t}\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar material = this.material;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\tif ( material === undefined ) return;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\t// Check boundingBox before continuing\n\n\t\t\t\tif ( geometry.boundingBox !== null ) {\n\n\t\t\t\t\tif ( ray.intersectsBox( geometry.boundingBox ) === false ) return;\n\n\t\t\t\t}\n\n\t\t\t\tvar intersection;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar a, b, c;\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar position = geometry.attributes.position;\n\t\t\t\t\tvar uv = geometry.attributes.uv;\n\t\t\t\t\tvar i, l;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\t// indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = index.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = index.getX( i );\n\t\t\t\t\t\t\tb = index.getX( i + 1 );\n\t\t\t\t\t\t\tc = index.getX( i + 2 );\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// non-indexed buffer geometry\n\n\t\t\t\t\t\tfor ( i = 0, l = position.count; i < l; i += 3 ) {\n\n\t\t\t\t\t\t\ta = i;\n\t\t\t\t\t\t\tb = i + 1;\n\t\t\t\t\t\t\tc = i + 2;\n\n\t\t\t\t\t\t\tintersection = checkBufferGeometryIntersection( this, raycaster, ray, position, uv, a, b, c );\n\n\t\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\t\tintersection.index = a; // triangle number in positions buffer semantics\n\t\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar fvA, fvB, fvC;\n\t\t\t\t\tvar isFaceMaterial = ( material && material.isMultiMaterial );\n\t\t\t\t\tvar materials = isFaceMaterial === true ? material.materials : null;\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar uvs;\n\n\t\t\t\t\tvar faceVertexUvs = geometry.faceVertexUvs[ 0 ];\n\t\t\t\t\tif ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;\n\n\t\t\t\t\tfor ( var f = 0, fl = faces.length; f < fl; f ++ ) {\n\n\t\t\t\t\t\tvar face = faces[ f ];\n\t\t\t\t\t\tvar faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material;\n\n\t\t\t\t\t\tif ( faceMaterial === undefined ) continue;\n\n\t\t\t\t\t\tfvA = vertices[ face.a ];\n\t\t\t\t\t\tfvB = vertices[ face.b ];\n\t\t\t\t\t\tfvC = vertices[ face.c ];\n\n\t\t\t\t\t\tif ( faceMaterial.morphTargets === true ) {\n\n\t\t\t\t\t\t\tvar morphTargets = geometry.morphTargets;\n\t\t\t\t\t\t\tvar morphInfluences = this.morphTargetInfluences;\n\n\t\t\t\t\t\t\tvA.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvB.set( 0, 0, 0 );\n\t\t\t\t\t\t\tvC.set( 0, 0, 0 );\n\n\t\t\t\t\t\t\tfor ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {\n\n\t\t\t\t\t\t\t\tvar influence = morphInfluences[ t ];\n\n\t\t\t\t\t\t\t\tif ( influence === 0 ) continue;\n\n\t\t\t\t\t\t\t\tvar targets = morphTargets[ t ].vertices;\n\n\t\t\t\t\t\t\t\tvA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence );\n\t\t\t\t\t\t\t\tvB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence );\n\t\t\t\t\t\t\t\tvC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvA.add( fvA );\n\t\t\t\t\t\t\tvB.add( fvB );\n\t\t\t\t\t\t\tvC.add( fvC );\n\n\t\t\t\t\t\t\tfvA = vA;\n\t\t\t\t\t\t\tfvB = vB;\n\t\t\t\t\t\t\tfvC = vC;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tintersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );\n\n\t\t\t\t\t\tif ( intersection ) {\n\n\t\t\t\t\t\t\tif ( uvs ) {\n\n\t\t\t\t\t\t\t\tvar uvs_f = uvs[ f ];\n\t\t\t\t\t\t\t\tuvA.copy( uvs_f[ 0 ] );\n\t\t\t\t\t\t\t\tuvB.copy( uvs_f[ 1 ] );\n\t\t\t\t\t\t\t\tuvC.copy( uvs_f[ 2 ] );\n\n\t\t\t\t\t\t\t\tintersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tintersection.face = face;\n\t\t\t\t\t\t\tintersection.faceIndex = f;\n\t\t\t\t\t\t\tintersects.push( intersection );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as\n\t */\n\n\tfunction BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'BoxGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tBoxGeometry.prototype = Object.create( Geometry.prototype );\n\tBoxGeometry.prototype.constructor = BoxGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\tdepth: depth,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tdepthSegments: depthSegments\n\t\t};\n\n\t\tvar scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor( widthSegments ) || 1;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\t\tdepthSegments = Math.floor( depthSegments ) || 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar numberOfVertices = 0;\n\t\tvar groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px\n\t\tbuildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx\n\t\tbuildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py\n\t\tbuildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny\n\t\tbuildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz\n\t\tbuildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {\n\n\t\t\tvar segmentWidth = width / gridX;\n\t\t\tvar segmentHeight = height / gridY;\n\n\t\t\tvar widthHalf = width / 2;\n\t\t\tvar heightHalf = height / 2;\n\t\t\tvar depthHalf = depth / 2;\n\n\t\t\tvar gridX1 = gridX + 1;\n\t\t\tvar gridY1 = gridY + 1;\n\n\t\t\tvar vertexCounter = 0;\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar ix, iy;\n\n\t\t\tvar vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\t\tvar y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\t\tvar x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = x * udir;\n\t\t\t\t\tvector[ v ] = y * vdir;\n\t\t\t\t\tvector[ w ] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[ u ] = 0;\n\t\t\t\t\tvector[ v ] = 0;\n\t\t\t\t\tvector[ w ] = depth > 0 ? 1 : - 1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push( vector.x, vector.y, vector.z );\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\t\tvar a = numberOfVertices + ix + gridX1 * iy;\n\t\t\t\t\tvar b = numberOfVertices + ix + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\t\tvar d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, materialIndex );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tnumberOfVertices += vertexCounter;\n\n\t\t}\n\n\t}\n\n\tBoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tBoxBufferGeometry.prototype.constructor = BoxBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );\n\n\t}\n\n\tPlaneGeometry.prototype = Object.create( Geometry.prototype );\n\tPlaneGeometry.prototype.constructor = PlaneGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as\n\t */\n\n\tfunction PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PlaneBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tvar width_half = width / 2;\n\t\tvar height_half = height / 2;\n\n\t\tvar gridX = Math.floor( widthSegments ) || 1;\n\t\tvar gridY = Math.floor( heightSegments ) || 1;\n\n\t\tvar gridX1 = gridX + 1;\n\t\tvar gridY1 = gridY + 1;\n\n\t\tvar segment_width = width / gridX;\n\t\tvar segment_height = height / gridY;\n\n\t\tvar ix, iy;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy < gridY1; iy ++ ) {\n\n\t\t\tvar y = iy * segment_height - height_half;\n\n\t\t\tfor ( ix = 0; ix < gridX1; ix ++ ) {\n\n\t\t\t\tvar x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push( x, - y, 0 );\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\tuvs.push( ix / gridX );\n\t\t\t\tuvs.push( 1 - ( iy / gridY ) );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < gridY; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < gridX; ix ++ ) {\n\n\t\t\t\tvar a = ix + gridX1 * iy;\n\t\t\t\tvar b = ix + gridX1 * ( iy + 1 );\n\t\t\t\tvar c = ( ix + 1 ) + gridX1 * ( iy + 1 );\n\t\t\t\tvar d = ( ix + 1 ) + gridX1 * iy;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tPlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction Camera() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Camera';\n\n\t\tthis.matrixWorldInverse = new Matrix4();\n\t\tthis.projectionMatrix = new Matrix4();\n\n\t}\n\n\tCamera.prototype = Object.create( Object3D.prototype );\n\tCamera.prototype.constructor = Camera;\n\n\tCamera.prototype.isCamera = true;\n\n\tCamera.prototype.getWorldDirection = function () {\n\n\t\tvar quaternion = new Quaternion();\n\n\t\treturn function getWorldDirection( optionalTarget ) {\n\n\t\t\tvar result = optionalTarget || new Vector3();\n\n\t\t\tthis.getWorldQuaternion( quaternion );\n\n\t\t\treturn result.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.lookAt = function () {\n\n\t\t// This routine does not support cameras with rotated and/or translated parent(s)\n\n\t\tvar m1 = new Matrix4();\n\n\t\treturn function lookAt( vector ) {\n\n\t\t\tm1.lookAt( this.position, vector, this.up );\n\n\t\t\tthis.quaternion.setFromRotationMatrix( m1 );\n\n\t\t};\n\n\t}();\n\n\tCamera.prototype.clone = function () {\n\n\t\treturn new this.constructor().copy( this );\n\n\t};\n\n\tCamera.prototype.copy = function ( source ) {\n\n\t\tObject3D.prototype.copy.call( this, source );\n\n\t\tthis.matrixWorldInverse.copy( source.matrixWorldInverse );\n\t\tthis.projectionMatrix.copy( source.projectionMatrix );\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author greggman / http://games.greggman.com/\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author tschw\n\t */\n\n\tfunction PerspectiveCamera( fov, aspect, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'PerspectiveCamera';\n\n\t\tthis.fov = fov !== undefined ? fov : 50;\n\t\tthis.zoom = 1;\n\n\t\tthis.near = near !== undefined ? near : 0.1;\n\t\tthis.far = far !== undefined ? far : 2000;\n\t\tthis.focus = 10;\n\n\t\tthis.aspect = aspect !== undefined ? aspect : 1;\n\t\tthis.view = null;\n\n\t\tthis.filmGauge = 35;\t// width of the film (default in millimeters)\n\t\tthis.filmOffset = 0;\t// horizontal film offset (same unit as gauge)\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tPerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: PerspectiveCamera,\n\n\t\tisPerspectiveCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.fov = source.fov;\n\t\t\tthis.zoom = source.zoom;\n\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\t\t\tthis.focus = source.focus;\n\n\t\t\tthis.aspect = source.aspect;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\tthis.filmGauge = source.filmGauge;\n\t\t\tthis.filmOffset = source.filmOffset;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t/**\n\t\t * Sets the FOV by focal length in respect to the current .filmGauge.\n\t\t *\n\t\t * The default film gauge is 35, so that the focal length can be specified for\n\t\t * a 35mm (full frame) camera.\n\t\t *\n\t\t * Values for focal length and film gauge must have the same unit.\n\t\t */\n\t\tsetFocalLength: function ( focalLength ) {\n\n\t\t\t// see http://www.bobatkins.com/photography/technical/field_of_view.html\n\t\t\tvar vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;\n\n\t\t\tthis.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope );\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\t/**\n\t\t * Calculates the focal length from the current .fov and .filmGauge.\n\t\t */\n\t\tgetFocalLength: function () {\n\n\t\t\tvar vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov );\n\n\t\t\treturn 0.5 * this.getFilmHeight() / vExtentSlope;\n\n\t\t},\n\n\t\tgetEffectiveFOV: function () {\n\n\t\t\treturn _Math.RAD2DEG * 2 * Math.atan(\n\t\t\t\t\tMath.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom );\n\n\t\t},\n\n\t\tgetFilmWidth: function () {\n\n\t\t\t// film not completely covered in portrait format (aspect < 1)\n\t\t\treturn this.filmGauge * Math.min( this.aspect, 1 );\n\n\t\t},\n\n\t\tgetFilmHeight: function () {\n\n\t\t\t// film not completely covered in landscape format (aspect > 1)\n\t\t\treturn this.filmGauge / Math.max( this.aspect, 1 );\n\n\t\t},\n\n\t\t/**\n\t\t * Sets an offset in a larger frustum. This is useful for multi-window or\n\t\t * multi-monitor/multi-machine setups.\n\t\t *\n\t\t * For example, if you have 3x2 monitors and each monitor is 1920x1080 and\n\t\t * the monitors are in grid like this\n\t\t *\n\t\t * +---+---+---+\n\t\t * | A | B | C |\n\t\t * +---+---+---+\n\t\t * | D | E | F |\n\t\t * +---+---+---+\n\t\t *\n\t\t * then for each monitor you would call it like this\n\t\t *\n\t\t * var w = 1920;\n\t\t * var h = 1080;\n\t\t * var fullWidth = w * 3;\n\t\t * var fullHeight = h * 2;\n\t\t *\n\t\t * --A--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );\n\t\t * --B--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );\n\t\t * --C--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );\n\t\t * --D--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );\n\t\t * --E--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );\n\t\t * --F--\n\t\t * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );\n\t\t *\n\t\t * Note there is no reason monitors have to be the same size or in a grid.\n\t\t */\n\t\tsetViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.aspect = fullWidth / fullHeight;\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar near = this.near,\n\t\t\t\ttop = near * Math.tan(\n\t\t\t\t\t\t_Math.DEG2RAD * 0.5 * this.fov ) / this.zoom,\n\t\t\t\theight = 2 * top,\n\t\t\t\twidth = this.aspect * height,\n\t\t\t\tleft = - 0.5 * width,\n\t\t\t\tview = this.view;\n\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar fullWidth = view.fullWidth,\n\t\t\t\t\tfullHeight = view.fullHeight;\n\n\t\t\t\tleft += view.offsetX * width / fullWidth;\n\t\t\t\ttop -= view.offsetY * height / fullHeight;\n\t\t\t\twidth *= view.width / fullWidth;\n\t\t\t\theight *= view.height / fullHeight;\n\n\t\t\t}\n\n\t\t\tvar skew = this.filmOffset;\n\t\t\tif ( skew !== 0 ) left += near * skew / this.getFilmWidth();\n\n\t\t\tthis.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.fov = this.fov;\n\t\t\tdata.object.zoom = this.zoom;\n\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\t\t\tdata.object.focus = this.focus;\n\n\t\t\tdata.object.aspect = this.aspect;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\tdata.object.filmGauge = this.filmGauge;\n\t\t\tdata.object.filmOffset = this.filmOffset;\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author arose / http://github.com/arose\n\t */\n\n\tfunction OrthographicCamera( left, right, top, bottom, near, far ) {\n\n\t\tCamera.call( this );\n\n\t\tthis.type = 'OrthographicCamera';\n\n\t\tthis.zoom = 1;\n\t\tthis.view = null;\n\n\t\tthis.left = left;\n\t\tthis.right = right;\n\t\tthis.top = top;\n\t\tthis.bottom = bottom;\n\n\t\tthis.near = ( near !== undefined ) ? near : 0.1;\n\t\tthis.far = ( far !== undefined ) ? far : 2000;\n\n\t\tthis.updateProjectionMatrix();\n\n\t}\n\n\tOrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {\n\n\t\tconstructor: OrthographicCamera,\n\n\t\tisOrthographicCamera: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tCamera.prototype.copy.call( this, source );\n\n\t\t\tthis.left = source.left;\n\t\t\tthis.right = source.right;\n\t\t\tthis.top = source.top;\n\t\t\tthis.bottom = source.bottom;\n\t\t\tthis.near = source.near;\n\t\t\tthis.far = source.far;\n\n\t\t\tthis.zoom = source.zoom;\n\t\t\tthis.view = source.view === null ? null : Object.assign( {}, source.view );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetViewOffset: function( fullWidth, fullHeight, x, y, width, height ) {\n\n\t\t\tthis.view = {\n\t\t\t\tfullWidth: fullWidth,\n\t\t\t\tfullHeight: fullHeight,\n\t\t\t\toffsetX: x,\n\t\t\t\toffsetY: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tclearViewOffset: function() {\n\n\t\t\tthis.view = null;\n\t\t\tthis.updateProjectionMatrix();\n\n\t\t},\n\n\t\tupdateProjectionMatrix: function () {\n\n\t\t\tvar dx = ( this.right - this.left ) / ( 2 * this.zoom );\n\t\t\tvar dy = ( this.top - this.bottom ) / ( 2 * this.zoom );\n\t\t\tvar cx = ( this.right + this.left ) / 2;\n\t\t\tvar cy = ( this.top + this.bottom ) / 2;\n\n\t\t\tvar left = cx - dx;\n\t\t\tvar right = cx + dx;\n\t\t\tvar top = cy + dy;\n\t\t\tvar bottom = cy - dy;\n\n\t\t\tif ( this.view !== null ) {\n\n\t\t\t\tvar zoomW = this.zoom / ( this.view.width / this.view.fullWidth );\n\t\t\t\tvar zoomH = this.zoom / ( this.view.height / this.view.fullHeight );\n\t\t\t\tvar scaleW = ( this.right - this.left ) / this.view.width;\n\t\t\t\tvar scaleH = ( this.top - this.bottom ) / this.view.height;\n\n\t\t\t\tleft += scaleW * ( this.view.offsetX / zoomW );\n\t\t\t\tright = left + scaleW * ( this.view.width / zoomW );\n\t\t\t\ttop -= scaleH * ( this.view.offsetY / zoomH );\n\t\t\t\tbottom = top - scaleH * ( this.view.height / zoomH );\n\n\t\t\t}\n\n\t\t\tthis.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.zoom = this.zoom;\n\t\t\tdata.object.left = this.left;\n\t\t\tdata.object.right = this.right;\n\t\t\tdata.object.top = this.top;\n\t\t\tdata.object.bottom = this.bottom;\n\t\t\tdata.object.near = this.near;\n\t\t\tdata.object.far = this.far;\n\n\t\t\tif ( this.view !== null ) data.object.view = Object.assign( {}, this.view );\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tvar type, size;\n\n\t\tfunction setIndex( index ) {\n\n\t\t\tif ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\t\t\t\tsize = 4;\n\n\t\t\t} else if ( index.array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\t\t\t\tsize = 2;\n\n\t\t\t} else {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\t\t\t\tsize = 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawElements( mode, count, type, start * size );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry, start, count ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\textension.drawElementsInstancedANGLE( mode, count, type, start * size, geometry.maxInstancedCount );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tsetMode: setMode,\n\t\t\tsetIndex: setIndex,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLBufferRenderer( gl, extensions, infoRender ) {\n\n\t\tvar mode;\n\n\t\tfunction setMode( value ) {\n\n\t\t\tmode = value;\n\n\t\t}\n\n\t\tfunction render( start, count ) {\n\n\t\t\tgl.drawArrays( mode, start, count );\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += count / 3;\n\n\t\t}\n\n\t\tfunction renderInstances( geometry ) {\n\n\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\tif ( extension === null ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar position = geometry.attributes.position;\n\n\t\t\tvar count = 0;\n\n\t\t\tif ( position.isInterleavedBufferAttribute ) {\n\n\t\t\t\tcount = position.data.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t} else {\n\n\t\t\t\tcount = position.count;\n\n\t\t\t\textension.drawArraysInstancedANGLE( mode, 0, count, geometry.maxInstancedCount );\n\n\t\t\t}\n\n\t\t\tinfoRender.calls ++;\n\t\t\tinfoRender.vertices += count * geometry.maxInstancedCount;\n\n\t\t\tif ( mode === gl.TRIANGLES ) infoRender.faces += geometry.maxInstancedCount * count / 3;\n\n\t\t}\n\n\t\treturn {\n\t\t\tsetMode: setMode,\n\t\t\trender: render,\n\t\t\trenderInstances: renderInstances\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLLights() {\n\n\t\tvar lights = {};\n\n\t\treturn {\n\n\t\t\tget: function ( light ) {\n\n\t\t\t\tif ( lights[ light.id ] !== undefined ) {\n\n\t\t\t\t\treturn lights[ light.id ];\n\n\t\t\t\t}\n\n\t\t\t\tvar uniforms;\n\n\t\t\t\tswitch ( light.type ) {\n\n\t\t\t\t\tcase 'DirectionalLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tconeCos: 0,\n\t\t\t\t\t\t\tpenumbraCos: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tdistance: 0,\n\t\t\t\t\t\t\tdecay: 0,\n\n\t\t\t\t\t\t\tshadow: false,\n\t\t\t\t\t\t\tshadowBias: 0,\n\t\t\t\t\t\t\tshadowRadius: 1,\n\t\t\t\t\t\t\tshadowMapSize: new Vector2()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tdirection: new Vector3(),\n\t\t\t\t\t\t\tskyColor: new Color(),\n\t\t\t\t\t\t\tgroundColor: new Color()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'RectAreaLight':\n\t\t\t\t\t\tuniforms = {\n\t\t\t\t\t\t\tcolor: new Color(),\n\t\t\t\t\t\t\tposition: new Vector3(),\n\t\t\t\t\t\t\thalfWidth: new Vector3(),\n\t\t\t\t\t\t\thalfHeight: new Vector3()\n\t\t\t\t\t\t\t// TODO (abelnation): set RectAreaLight shadow uniforms\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tlights[ light.id ] = uniforms;\n\n\t\t\t\treturn uniforms;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction addLineNumbers( string ) {\n\n\t\tvar lines = string.split( '\\n' );\n\n\t\tfor ( var i = 0; i < lines.length; i ++ ) {\n\n\t\t\tlines[ i ] = ( i + 1 ) + ': ' + lines[ i ];\n\n\t\t}\n\n\t\treturn lines.join( '\\n' );\n\n\t}\n\n\tfunction WebGLShader( gl, type, string ) {\n\n\t\tvar shader = gl.createShader( type );\n\n\t\tgl.shaderSource( shader, string );\n\t\tgl.compileShader( shader );\n\n\t\tif ( gl.getShaderParameter( shader, gl.COMPILE_STATUS ) === false ) {\n\n\t\t\tconsole.error( 'THREE.WebGLShader: Shader couldn\\'t compile.' );\n\n\t\t}\n\n\t\tif ( gl.getShaderInfoLog( shader ) !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) );\n\n\t\t}\n\n\t\t// --enable-privileged-webgl-extension\n\t\t// console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );\n\n\t\treturn shader;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar programIdCount = 0;\n\n\tfunction getEncodingComponents( encoding ) {\n\n\t\tswitch ( encoding ) {\n\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn [ 'Linear','( value )' ];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn [ 'sRGB','( value )' ];\n\t\t\tcase RGBEEncoding:\n\t\t\t\treturn [ 'RGBE','( value )' ];\n\t\t\tcase RGBM7Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 7.0 )' ];\n\t\t\tcase RGBM16Encoding:\n\t\t\t\treturn [ 'RGBM','( value, 16.0 )' ];\n\t\t\tcase RGBDEncoding:\n\t\t\t\treturn [ 'RGBD','( value, 256.0 )' ];\n\t\t\tcase GammaEncoding:\n\t\t\t\treturn [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ];\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported encoding: ' + encoding );\n\n\t\t}\n\n\t}\n\n\tfunction getTexelDecodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return \" + components[ 0 ] + \"ToLinear\" + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getTexelEncodingFunction( functionName, encoding ) {\n\n\t\tvar components = getEncodingComponents( encoding );\n\t\treturn \"vec4 \" + functionName + \"( vec4 value ) { return LinearTo\" + components[ 0 ] + components[ 1 ] + \"; }\";\n\n\t}\n\n\tfunction getToneMappingFunction( functionName, toneMapping ) {\n\n\t\tvar toneMappingName;\n\n\t\tswitch ( toneMapping ) {\n\n\t\t\tcase LinearToneMapping:\n\t\t\t\ttoneMappingName = \"Linear\";\n\t\t\t\tbreak;\n\n\t\t\tcase ReinhardToneMapping:\n\t\t\t\ttoneMappingName = \"Reinhard\";\n\t\t\t\tbreak;\n\n\t\t\tcase Uncharted2ToneMapping:\n\t\t\t\ttoneMappingName = \"Uncharted2\";\n\t\t\t\tbreak;\n\n\t\t\tcase CineonToneMapping:\n\t\t\t\ttoneMappingName = \"OptimizedCineon\";\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error( 'unsupported toneMapping: ' + toneMapping );\n\n\t\t}\n\n\t\treturn \"vec3 \" + functionName + \"( vec3 color ) { return \" + toneMappingName + \"ToneMapping( color ); }\";\n\n\t}\n\n\tfunction generateExtensions( extensions, parameters, rendererExtensions ) {\n\n\t\textensions = extensions || {};\n\n\t\tvar chunks = [\n\t\t\t( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',\n\t\t\t( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',\n\t\t\t( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',\n\t\t\t( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''\n\t\t];\n\n\t\treturn chunks.filter( filterEmptyLine ).join( '\\n' );\n\n\t}\n\n\tfunction generateDefines( defines ) {\n\n\t\tvar chunks = [];\n\n\t\tfor ( var name in defines ) {\n\n\t\t\tvar value = defines[ name ];\n\n\t\t\tif ( value === false ) continue;\n\n\t\t\tchunks.push( '#define ' + name + ' ' + value );\n\n\t\t}\n\n\t\treturn chunks.join( '\\n' );\n\n\t}\n\n\tfunction fetchAttributeLocations( gl, program, identifiers ) {\n\n\t\tvar attributes = {};\n\n\t\tvar n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );\n\n\t\tfor ( var i = 0; i < n; i ++ ) {\n\n\t\t\tvar info = gl.getActiveAttrib( program, i );\n\t\t\tvar name = info.name;\n\n\t\t\t// console.log(\"THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:\", name, i );\n\n\t\t\tattributes[ name ] = gl.getAttribLocation( program, name );\n\n\t\t}\n\n\t\treturn attributes;\n\n\t}\n\n\tfunction filterEmptyLine( string ) {\n\n\t\treturn string !== '';\n\n\t}\n\n\tfunction replaceLightNums( string, parameters ) {\n\n\t\treturn string\n\t\t\t.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )\n\t\t\t.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )\n\t\t\t.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )\n\t\t\t.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )\n\t\t\t.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );\n\n\t}\n\n\tfunction parseIncludes( string ) {\n\n\t\tvar pattern = /#include +<([\\w\\d.]+)>/g;\n\n\t\tfunction replace( match, include ) {\n\n\t\t\tvar replace = ShaderChunk[ include ];\n\n\t\t\tif ( replace === undefined ) {\n\n\t\t\t\tthrow new Error( 'Can not resolve #include <' + include + '>' );\n\n\t\t\t}\n\n\t\t\treturn parseIncludes( replace );\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction unrollLoops( string ) {\n\n\t\tvar pattern = /for \\( int i \\= (\\d+)\\; i < (\\d+)\\; i \\+\\+ \\) \\{([\\s\\S]+?)(?=\\})\\}/g;\n\n\t\tfunction replace( match, start, end, snippet ) {\n\n\t\t\tvar unroll = '';\n\n\t\t\tfor ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {\n\n\t\t\t\tunroll += snippet.replace( /\\[ i \\]/g, '[ ' + i + ' ]' );\n\n\t\t\t}\n\n\t\t\treturn unroll;\n\n\t\t}\n\n\t\treturn string.replace( pattern, replace );\n\n\t}\n\n\tfunction WebGLProgram( renderer, code, material, parameters ) {\n\n\t\tvar gl = renderer.context;\n\n\t\tvar extensions = material.extensions;\n\t\tvar defines = material.defines;\n\n\t\tvar vertexShader = material.__webglShader.vertexShader;\n\t\tvar fragmentShader = material.__webglShader.fragmentShader;\n\n\t\tvar shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';\n\n\t\tif ( parameters.shadowMapType === PCFShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';\n\n\t\t} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {\n\n\t\t\tshadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';\n\n\t\t}\n\n\t\tvar envMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\tvar envMapModeDefine = 'ENVMAP_MODE_REFLECTION';\n\t\tvar envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\n\t\tif ( parameters.envMap ) {\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase EquirectangularReflectionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SphericalReflectionMapping:\n\t\t\t\t\tenvMapTypeDefine = 'ENVMAP_TYPE_SPHERE';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.envMap.mapping ) {\n\n\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\tcase EquirectangularRefractionMapping:\n\t\t\t\t\tenvMapModeDefine = 'ENVMAP_MODE_REFRACTION';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tswitch ( material.combine ) {\n\n\t\t\t\tcase MultiplyOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase MixOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_MIX';\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase AddOperation:\n\t\t\t\t\tenvMapBlendingDefine = 'ENVMAP_BLENDING_ADD';\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;\n\n\t\t// console.log( 'building new program ' );\n\n\t\t//\n\n\t\tvar customExtensions = generateExtensions( extensions, parameters, renderer.extensions );\n\n\t\tvar customDefines = generateDefines( defines );\n\n\t\t//\n\n\t\tvar program = gl.createProgram();\n\n\t\tvar prefixVertex, prefixFragment;\n\n\t\tif ( material.isRawShaderMaterial ) {\n\n\t\t\tprefixVertex = [\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\t\t\t\tcustomDefines,\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t} else {\n\n\t\t\tprefixVertex = [\n\n\t \n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t'#define MAX_BONES ' + parameters.maxBones,\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.skinning ? '#define USE_SKINNING' : '',\n\t\t\t\tparameters.useVertexTexture ? '#define BONE_TEXTURE' : '',\n\n\t\t\t\tparameters.morphTargets ? '#define USE_MORPHTARGETS' : '',\n\t\t\t\tparameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\t'uniform mat4 modelMatrix;',\n\t\t\t\t'uniform mat4 modelViewMatrix;',\n\t\t\t\t'uniform mat4 projectionMatrix;',\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform mat3 normalMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t'attribute vec3 position;',\n\t\t\t\t'attribute vec3 normal;',\n\t\t\t\t'attribute vec2 uv;',\n\n\t\t\t\t'#ifdef USE_COLOR',\n\n\t\t\t\t'\tattribute vec3 color;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_MORPHTARGETS',\n\n\t\t\t\t'\tattribute vec3 morphTarget0;',\n\t\t\t\t'\tattribute vec3 morphTarget1;',\n\t\t\t\t'\tattribute vec3 morphTarget2;',\n\t\t\t\t'\tattribute vec3 morphTarget3;',\n\n\t\t\t\t'\t#ifdef USE_MORPHNORMALS',\n\n\t\t\t\t'\t\tattribute vec3 morphNormal0;',\n\t\t\t\t'\t\tattribute vec3 morphNormal1;',\n\t\t\t\t'\t\tattribute vec3 morphNormal2;',\n\t\t\t\t'\t\tattribute vec3 morphNormal3;',\n\n\t\t\t\t'\t#else',\n\n\t\t\t\t'\t\tattribute vec3 morphTarget4;',\n\t\t\t\t'\t\tattribute vec3 morphTarget5;',\n\t\t\t\t'\t\tattribute vec3 morphTarget6;',\n\t\t\t\t'\t\tattribute vec3 morphTarget7;',\n\n\t\t\t\t'\t#endif',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'#ifdef USE_SKINNING',\n\n\t\t\t\t'\tattribute vec4 skinIndex;',\n\t\t\t\t'\tattribute vec4 skinWeight;',\n\n\t\t\t\t'#endif',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t\tprefixFragment = [\n\n\t\t\t\tcustomExtensions,\n\n\t\t\t\t'precision ' + parameters.precision + ' float;',\n\t\t\t\t'precision ' + parameters.precision + ' int;',\n\n\t\t\t\t'#define SHADER_NAME ' + material.__webglShader.name,\n\n\t\t\t\tcustomDefines,\n\n\t\t\t\tparameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '',\n\n\t\t\t\t'#define GAMMA_FACTOR ' + gammaFactorDefine,\n\n\t\t\t\t( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',\n\t\t\t\t( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',\n\n\t\t\t\tparameters.map ? '#define USE_MAP' : '',\n\t\t\t\tparameters.envMap ? '#define USE_ENVMAP' : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapTypeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapModeDefine : '',\n\t\t\t\tparameters.envMap ? '#define ' + envMapBlendingDefine : '',\n\t\t\t\tparameters.lightMap ? '#define USE_LIGHTMAP' : '',\n\t\t\t\tparameters.aoMap ? '#define USE_AOMAP' : '',\n\t\t\t\tparameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',\n\t\t\t\tparameters.bumpMap ? '#define USE_BUMPMAP' : '',\n\t\t\t\tparameters.normalMap ? '#define USE_NORMALMAP' : '',\n\t\t\t\tparameters.specularMap ? '#define USE_SPECULARMAP' : '',\n\t\t\t\tparameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',\n\t\t\t\tparameters.metalnessMap ? '#define USE_METALNESSMAP' : '',\n\t\t\t\tparameters.alphaMap ? '#define USE_ALPHAMAP' : '',\n\t\t\t\tparameters.vertexColors ? '#define USE_COLOR' : '',\n\n\t\t\t\tparameters.gradientMap ? '#define USE_GRADIENTMAP' : '',\n\n\t\t\t\tparameters.flatShading ? '#define FLAT_SHADED' : '',\n\n\t\t\t\tparameters.doubleSided ? '#define DOUBLE_SIDED' : '',\n\t\t\t\tparameters.flipSided ? '#define FLIP_SIDED' : '',\n\n\t\t\t\t'#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes,\n\t\t\t\t'#define UNION_CLIPPING_PLANES ' + (parameters.numClippingPlanes - parameters.numClipIntersection),\n\n\t\t\t\tparameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',\n\t\t\t\tparameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',\n\n\t\t\t\tparameters.premultipliedAlpha ? \"#define PREMULTIPLIED_ALPHA\" : '',\n\n\t\t\t\tparameters.physicallyCorrectLights ? \"#define PHYSICALLY_CORRECT_LIGHTS\" : '',\n\n\t\t\t\tparameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',\n\t\t\t\tparameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',\n\n\t\t\t\tparameters.envMap && renderer.extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',\n\n\t\t\t\t'uniform mat4 viewMatrix;',\n\t\t\t\t'uniform vec3 cameraPosition;',\n\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? \"#define TONE_MAPPING\" : '',\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below\n\t\t\t\t( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( \"toneMapping\", parameters.toneMapping ) : '',\n\n\t\t\t\t( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below\n\t\t\t\tparameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',\n\t\t\t\tparameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',\n\t\t\t\tparameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',\n\t\t\t\tparameters.outputEncoding ? getTexelEncodingFunction( \"linearToOutputTexel\", parameters.outputEncoding ) : '',\n\n\t\t\t\tparameters.depthPacking ? \"#define DEPTH_PACKING \" + material.depthPacking : '',\n\n\t\t\t\t'\\n'\n\n\t\t\t].filter( filterEmptyLine ).join( '\\n' );\n\n\t\t}\n\n\t\tvertexShader = parseIncludes( vertexShader, parameters );\n\t\tvertexShader = replaceLightNums( vertexShader, parameters );\n\n\t\tfragmentShader = parseIncludes( fragmentShader, parameters );\n\t\tfragmentShader = replaceLightNums( fragmentShader, parameters );\n\n\t\tif ( ! material.isShaderMaterial ) {\n\n\t\t\tvertexShader = unrollLoops( vertexShader );\n\t\t\tfragmentShader = unrollLoops( fragmentShader );\n\n\t\t}\n\n\t\tvar vertexGlsl = prefixVertex + vertexShader;\n\t\tvar fragmentGlsl = prefixFragment + fragmentShader;\n\n\t\t// console.log( '*VERTEX*', vertexGlsl );\n\t\t// console.log( '*FRAGMENT*', fragmentGlsl );\n\n\t\tvar glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );\n\t\tvar glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );\n\n\t\tgl.attachShader( program, glVertexShader );\n\t\tgl.attachShader( program, glFragmentShader );\n\n\t\t// Force a particular attribute to index 0.\n\n\t\tif ( material.index0AttributeName !== undefined ) {\n\n\t\t\tgl.bindAttribLocation( program, 0, material.index0AttributeName );\n\n\t\t} else if ( parameters.morphTargets === true ) {\n\n\t\t\t// programs with morphTargets displace position out of attribute 0\n\t\t\tgl.bindAttribLocation( program, 0, 'position' );\n\n\t\t}\n\n\t\tgl.linkProgram( program );\n\n\t\tvar programLog = gl.getProgramInfoLog( program );\n\t\tvar vertexLog = gl.getShaderInfoLog( glVertexShader );\n\t\tvar fragmentLog = gl.getShaderInfoLog( glFragmentShader );\n\n\t\tvar runnable = true;\n\t\tvar haveDiagnostics = true;\n\n\t\t// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );\n\t\t// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );\n\n\t\tif ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {\n\n\t\t\trunnable = false;\n\n\t\t\tconsole.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );\n\n\t\t} else if ( programLog !== '' ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );\n\n\t\t} else if ( vertexLog === '' || fragmentLog === '' ) {\n\n\t\t\thaveDiagnostics = false;\n\n\t\t}\n\n\t\tif ( haveDiagnostics ) {\n\n\t\t\tthis.diagnostics = {\n\n\t\t\t\trunnable: runnable,\n\t\t\t\tmaterial: material,\n\n\t\t\t\tprogramLog: programLog,\n\n\t\t\t\tvertexShader: {\n\n\t\t\t\t\tlog: vertexLog,\n\t\t\t\t\tprefix: prefixVertex\n\n\t\t\t\t},\n\n\t\t\t\tfragmentShader: {\n\n\t\t\t\t\tlog: fragmentLog,\n\t\t\t\t\tprefix: prefixFragment\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t// clean up\n\n\t\tgl.deleteShader( glVertexShader );\n\t\tgl.deleteShader( glFragmentShader );\n\n\t\t// set up caching for uniform locations\n\n\t\tvar cachedUniforms;\n\n\t\tthis.getUniforms = function() {\n\n\t\t\tif ( cachedUniforms === undefined ) {\n\n\t\t\t\tcachedUniforms =\n\t\t\t\t\tnew WebGLUniforms( gl, program, renderer );\n\n\t\t\t}\n\n\t\t\treturn cachedUniforms;\n\n\t\t};\n\n\t\t// set up caching for attribute locations\n\n\t\tvar cachedAttributes;\n\n\t\tthis.getAttributes = function() {\n\n\t\t\tif ( cachedAttributes === undefined ) {\n\n\t\t\t\tcachedAttributes = fetchAttributeLocations( gl, program );\n\n\t\t\t}\n\n\t\t\treturn cachedAttributes;\n\n\t\t};\n\n\t\t// free resource\n\n\t\tthis.destroy = function() {\n\n\t\t\tgl.deleteProgram( program );\n\t\t\tthis.program = undefined;\n\n\t\t};\n\n\t\t// DEPRECATED\n\n\t\tObject.defineProperties( this, {\n\n\t\t\tuniforms: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );\n\t\t\t\t\treturn this.getUniforms();\n\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tattributes: {\n\t\t\t\tget: function() {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );\n\t\t\t\t\treturn this.getAttributes();\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t} );\n\n\n\t\t//\n\n\t\tthis.id = programIdCount ++;\n\t\tthis.code = code;\n\t\tthis.usedTimes = 1;\n\t\tthis.program = program;\n\t\tthis.vertexShader = glVertexShader;\n\t\tthis.fragmentShader = glFragmentShader;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLPrograms( renderer, capabilities ) {\n\n\t\tvar programs = [];\n\n\t\tvar shaderIDs = {\n\t\t\tMeshDepthMaterial: 'depth',\n\t\t\tMeshNormalMaterial: 'normal',\n\t\t\tMeshBasicMaterial: 'basic',\n\t\t\tMeshLambertMaterial: 'lambert',\n\t\t\tMeshPhongMaterial: 'phong',\n\t\t\tMeshToonMaterial: 'phong',\n\t\t\tMeshStandardMaterial: 'physical',\n\t\t\tMeshPhysicalMaterial: 'physical',\n\t\t\tLineBasicMaterial: 'basic',\n\t\t\tLineDashedMaterial: 'dashed',\n\t\t\tPointsMaterial: 'points'\n\t\t};\n\n\t\tvar parameterNames = [\n\t\t\t\"precision\", \"supportsVertexTextures\", \"map\", \"mapEncoding\", \"envMap\", \"envMapMode\", \"envMapEncoding\",\n\t\t\t\"lightMap\", \"aoMap\", \"emissiveMap\", \"emissiveMapEncoding\", \"bumpMap\", \"normalMap\", \"displacementMap\", \"specularMap\",\n\t\t\t\"roughnessMap\", \"metalnessMap\", \"gradientMap\",\n\t\t\t\"alphaMap\", \"combine\", \"vertexColors\", \"fog\", \"useFog\", \"fogExp\",\n\t\t\t\"flatShading\", \"sizeAttenuation\", \"logarithmicDepthBuffer\", \"skinning\",\n\t\t\t\"maxBones\", \"useVertexTexture\", \"morphTargets\", \"morphNormals\",\n\t\t\t\"maxMorphTargets\", \"maxMorphNormals\", \"premultipliedAlpha\",\n\t\t\t\"numDirLights\", \"numPointLights\", \"numSpotLights\", \"numHemiLights\", \"numRectAreaLights\",\n\t\t\t\"shadowMapEnabled\", \"shadowMapType\", \"toneMapping\", 'physicallyCorrectLights',\n\t\t\t\"alphaTest\", \"doubleSided\", \"flipSided\", \"numClippingPlanes\", \"numClipIntersection\", \"depthPacking\"\n\t\t];\n\n\n\t\tfunction allocateBones( object ) {\n\n\t\t\tif ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {\n\n\t\t\t\treturn 1024;\n\n\t\t\t} else {\n\n\t\t\t\t// default for when object is not specified\n\t\t\t\t// ( for example when prebuilding shader to be used with multiple objects )\n\t\t\t\t//\n\t\t\t\t// - leave some extra space for other uniforms\n\t\t\t\t// - limit here is ANGLE's 254 max uniform vectors\n\t\t\t\t// (up to 54 should be safe)\n\n\t\t\t\tvar nVertexUniforms = capabilities.maxVertexUniforms;\n\t\t\t\tvar nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );\n\n\t\t\t\tvar maxBones = nVertexMatrices;\n\n\t\t\t\tif ( object !== undefined && (object && object.isSkinnedMesh) ) {\n\n\t\t\t\t\tmaxBones = Math.min( object.skeleton.bones.length, maxBones );\n\n\t\t\t\t\tif ( maxBones < object.skeleton.bones.length ) {\n\n\t\t\t\t\t\tconsole.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn maxBones;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getTextureEncodingFromMap( map, gammaOverrideLinear ) {\n\n\t\t\tvar encoding;\n\n\t\t\tif ( ! map ) {\n\n\t\t\t\tencoding = LinearEncoding;\n\n\t\t\t} else if ( map.isTexture ) {\n\n\t\t\t\tencoding = map.encoding;\n\n\t\t\t} else if ( map.isWebGLRenderTarget ) {\n\n\t\t\t\tconsole.warn( \"THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\tencoding = map.texture.encoding;\n\n\t\t\t}\n\n\t\t\t// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.\n\t\t\tif ( encoding === LinearEncoding && gammaOverrideLinear ) {\n\n\t\t\t\tencoding = GammaEncoding;\n\n\t\t\t}\n\n\t\t\treturn encoding;\n\n\t\t}\n\n\t\tthis.getParameters = function ( material, lights, fog, nClipPlanes, nClipIntersection, object ) {\n\n\t\t\tvar shaderID = shaderIDs[ material.type ];\n\n\t\t\t// heuristics to create shader parameters according to lights in the scene\n\t\t\t// (not to blow over maxLights budget)\n\n\t\t\tvar maxBones = allocateBones( object );\n\t\t\tvar precision = renderer.getPrecision();\n\n\t\t\tif ( material.precision !== null ) {\n\n\t\t\t\tprecision = capabilities.getMaxPrecision( material.precision );\n\n\t\t\t\tif ( precision !== material.precision ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar currentRenderTarget = renderer.getCurrentRenderTarget();\n\n\t\t\tvar parameters = {\n\n\t\t\t\tshaderID: shaderID,\n\n\t\t\t\tprecision: precision,\n\t\t\t\tsupportsVertexTextures: capabilities.vertexTextures,\n\t\t\t\toutputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),\n\t\t\t\tmap: !! material.map,\n\t\t\t\tmapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),\n\t\t\t\tenvMap: !! material.envMap,\n\t\t\t\tenvMapMode: material.envMap && material.envMap.mapping,\n\t\t\t\tenvMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),\n\t\t\t\tenvMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),\n\t\t\t\tlightMap: !! material.lightMap,\n\t\t\t\taoMap: !! material.aoMap,\n\t\t\t\temissiveMap: !! material.emissiveMap,\n\t\t\t\temissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),\n\t\t\t\tbumpMap: !! material.bumpMap,\n\t\t\t\tnormalMap: !! material.normalMap,\n\t\t\t\tdisplacementMap: !! material.displacementMap,\n\t\t\t\troughnessMap: !! material.roughnessMap,\n\t\t\t\tmetalnessMap: !! material.metalnessMap,\n\t\t\t\tspecularMap: !! material.specularMap,\n\t\t\t\talphaMap: !! material.alphaMap,\n\n\t\t\t\tgradientMap: !! material.gradientMap,\n\n\t\t\t\tcombine: material.combine,\n\n\t\t\t\tvertexColors: material.vertexColors,\n\n\t\t\t\tfog: !! fog,\n\t\t\t\tuseFog: material.fog,\n\t\t\t\tfogExp: (fog && fog.isFogExp2),\n\n\t\t\t\tflatShading: material.shading === FlatShading,\n\n\t\t\t\tsizeAttenuation: material.sizeAttenuation,\n\t\t\t\tlogarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,\n\n\t\t\t\tskinning: material.skinning,\n\t\t\t\tmaxBones: maxBones,\n\t\t\t\tuseVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,\n\n\t\t\t\tmorphTargets: material.morphTargets,\n\t\t\t\tmorphNormals: material.morphNormals,\n\t\t\t\tmaxMorphTargets: renderer.maxMorphTargets,\n\t\t\t\tmaxMorphNormals: renderer.maxMorphNormals,\n\n\t\t\t\tnumDirLights: lights.directional.length,\n\t\t\t\tnumPointLights: lights.point.length,\n\t\t\t\tnumSpotLights: lights.spot.length,\n\t\t\t\tnumRectAreaLights: lights.rectArea.length,\n\t\t\t\tnumHemiLights: lights.hemi.length,\n\n\t\t\t\tnumClippingPlanes: nClipPlanes,\n\t\t\t\tnumClipIntersection: nClipIntersection,\n\n\t\t\t\tshadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,\n\t\t\t\tshadowMapType: renderer.shadowMap.type,\n\n\t\t\t\ttoneMapping: renderer.toneMapping,\n\t\t\t\tphysicallyCorrectLights: renderer.physicallyCorrectLights,\n\n\t\t\t\tpremultipliedAlpha: material.premultipliedAlpha,\n\n\t\t\t\talphaTest: material.alphaTest,\n\t\t\t\tdoubleSided: material.side === DoubleSide,\n\t\t\t\tflipSided: material.side === BackSide,\n\n\t\t\t\tdepthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false\n\n\t\t\t};\n\n\t\t\treturn parameters;\n\n\t\t};\n\n\t\tthis.getProgramCode = function ( material, parameters ) {\n\n\t\t\tvar array = [];\n\n\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\tarray.push( parameters.shaderID );\n\n\t\t\t} else {\n\n\t\t\t\tarray.push( material.fragmentShader );\n\t\t\t\tarray.push( material.vertexShader );\n\n\t\t\t}\n\n\t\t\tif ( material.defines !== undefined ) {\n\n\t\t\t\tfor ( var name in material.defines ) {\n\n\t\t\t\t\tarray.push( name );\n\t\t\t\t\tarray.push( material.defines[ name ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < parameterNames.length; i ++ ) {\n\n\t\t\t\tarray.push( parameters[ parameterNames[ i ] ] );\n\n\t\t\t}\n\n\t\t\treturn array.join();\n\n\t\t};\n\n\t\tthis.acquireProgram = function ( material, parameters, code ) {\n\n\t\t\tvar program;\n\n\t\t\t// Check if code has been already compiled\n\t\t\tfor ( var p = 0, pl = programs.length; p < pl; p ++ ) {\n\n\t\t\t\tvar programInfo = programs[ p ];\n\n\t\t\t\tif ( programInfo.code === code ) {\n\n\t\t\t\t\tprogram = programInfo;\n\t\t\t\t\t++ program.usedTimes;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\tprogram = new WebGLProgram( renderer, code, material, parameters );\n\t\t\t\tprograms.push( program );\n\n\t\t\t}\n\n\t\t\treturn program;\n\n\t\t};\n\n\t\tthis.releaseProgram = function( program ) {\n\n\t\t\tif ( -- program.usedTimes === 0 ) {\n\n\t\t\t\t// Remove from unordered set\n\t\t\t\tvar i = programs.indexOf( program );\n\t\t\t\tprograms[ i ] = programs[ programs.length - 1 ];\n\t\t\t\tprograms.pop();\n\n\t\t\t\t// Free WebGL resources\n\t\t\t\tprogram.destroy();\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Exposed for resource monitoring & error feedback via renderer.info:\n\t\tthis.programs = programs;\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLGeometries( gl, properties, info ) {\n\n\t\tvar geometries = {};\n\n\t\tfunction onGeometryDispose( event ) {\n\n\t\t\tvar geometry = event.target;\n\t\t\tvar buffergeometry = geometries[ geometry.id ];\n\n\t\t\tif ( buffergeometry.index !== null ) {\n\n\t\t\t\tdeleteAttribute( buffergeometry.index );\n\n\t\t\t}\n\n\t\t\tdeleteAttributes( buffergeometry.attributes );\n\n\t\t\tgeometry.removeEventListener( 'dispose', onGeometryDispose );\n\n\t\t\tdelete geometries[ geometry.id ];\n\n\t\t\t// TODO\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe ) {\n\n\t\t\t\tdeleteAttribute( property.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( geometry );\n\n\t\t\tvar bufferproperty = properties.get( buffergeometry );\n\n\t\t\tif ( bufferproperty.wireframe ) {\n\n\t\t\t\tdeleteAttribute( bufferproperty.wireframe );\n\n\t\t\t}\n\n\t\t\tproperties.delete( buffergeometry );\n\n\t\t\t//\n\n\t\t\tinfo.memory.geometries --;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction deleteAttribute( attribute ) {\n\n\t\t\tvar buffer = getAttributeBuffer( attribute );\n\n\t\t\tif ( buffer !== undefined ) {\n\n\t\t\t\tgl.deleteBuffer( buffer );\n\t\t\t\tremoveAttributeBuffer( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction deleteAttributes( attributes ) {\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tdeleteAttribute( attributes[ name ] );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction removeAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\tproperties.delete( attribute.data );\n\n\t\t\t} else {\n\n\t\t\t\tproperties.delete( attribute );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar geometry = object.geometry;\n\n\t\t\t\tif ( geometries[ geometry.id ] !== undefined ) {\n\n\t\t\t\t\treturn geometries[ geometry.id ];\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.addEventListener( 'dispose', onGeometryDispose );\n\n\t\t\t\tvar buffergeometry;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tbuffergeometry = geometry;\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tif ( geometry._bufferGeometry === undefined ) {\n\n\t\t\t\t\t\tgeometry._bufferGeometry = new BufferGeometry().setFromObject( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbuffergeometry = geometry._bufferGeometry;\n\n\t\t\t\t}\n\n\t\t\t\tgeometries[ geometry.id ] = buffergeometry;\n\n\t\t\t\tinfo.memory.geometries ++;\n\n\t\t\t\treturn buffergeometry;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLObjects( gl, properties, info ) {\n\n\t\tvar geometries = new WebGLGeometries( gl, properties, info );\n\n\t\t//\n\n\t\tfunction update( object ) {\n\n\t\t\t// TODO: Avoid updating twice (when using shadowMap). Maybe add frame counter.\n\n\t\t\tvar geometry = geometries.get( object );\n\n\t\t\tif ( object.geometry.isGeometry ) {\n\n\t\t\t\tgeometry.updateFromObject( object );\n\n\t\t\t}\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tupdateAttribute( index, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\tfor ( var name in attributes ) {\n\n\t\t\t\tupdateAttribute( attributes[ name ], gl.ARRAY_BUFFER );\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\tfor ( var name in morphAttributes ) {\n\n\t\t\t\tvar array = morphAttributes[ name ];\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i ++ ) {\n\n\t\t\t\t\tupdateAttribute( array[ i ], gl.ARRAY_BUFFER );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t\tfunction updateAttribute( attribute, bufferType ) {\n\n\t\t\tvar data = ( attribute.isInterleavedBufferAttribute ) ? attribute.data : attribute;\n\n\t\t\tvar attributeProperties = properties.get( data );\n\n\t\t\tif ( attributeProperties.__webglBuffer === undefined ) {\n\n\t\t\t\tcreateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t} else if ( attributeProperties.version !== data.version ) {\n\n\t\t\t\tupdateBuffer( attributeProperties, data, bufferType );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction createBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tattributeProperties.__webglBuffer = gl.createBuffer();\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tvar usage = data.dynamic ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW;\n\n\t\t\tgl.bufferData( bufferType, data.array, usage );\n\n\t\t\tvar type = gl.FLOAT;\n\t\t\tvar array = data.array;\n\n\t\t\tif ( array instanceof Float32Array ) {\n\n\t\t\t\ttype = gl.FLOAT;\n\n\t\t\t} else if ( array instanceof Float64Array ) {\n\n\t\t\t\tconsole.warn( \"Unsupported data buffer format: Float64Array\" );\n\n\t\t\t} else if ( array instanceof Uint16Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_SHORT;\n\n\t\t\t} else if ( array instanceof Int16Array ) {\n\n\t\t\t\ttype = gl.SHORT;\n\n\t\t\t} else if ( array instanceof Uint32Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_INT;\n\n\t\t\t} else if ( array instanceof Int32Array ) {\n\n\t\t\t\ttype = gl.INT;\n\n\t\t\t} else if ( array instanceof Int8Array ) {\n\n\t\t\t\ttype = gl.BYTE;\n\n\t\t\t} else if ( array instanceof Uint8Array ) {\n\n\t\t\t\ttype = gl.UNSIGNED_BYTE;\n\n\t\t\t}\n\n\t\t\tattributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;\n\t\t\tattributeProperties.type = type;\n\t\t\tattributeProperties.version = data.version;\n\n\t\t\tdata.onUploadCallback();\n\n\t\t}\n\n\t\tfunction updateBuffer( attributeProperties, data, bufferType ) {\n\n\t\t\tgl.bindBuffer( bufferType, attributeProperties.__webglBuffer );\n\n\t\t\tif ( data.dynamic === false ) {\n\n\t\t\t\tgl.bufferData( bufferType, data.array, gl.STATIC_DRAW );\n\n\t\t\t} else if ( data.updateRange.count === - 1 ) {\n\n\t\t\t\t// Not using update ranges\n\n\t\t\t\tgl.bufferSubData( bufferType, 0, data.array );\n\n\t\t\t} else if ( data.updateRange.count === 0 ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' );\n\n\t\t\t} else {\n\n\t\t\t\tgl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,\n\t\t\t\t\t\t\t\t data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );\n\n\t\t\t\tdata.updateRange.count = 0; // reset range\n\n\t\t\t}\n\n\t\t\tattributeProperties.version = data.version;\n\n\t\t}\n\n\t\tfunction getAttributeBuffer( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data ).__webglBuffer;\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute ).__webglBuffer;\n\n\t\t}\n\n\t\tfunction getAttributeProperties( attribute ) {\n\n\t\t\tif ( attribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\treturn properties.get( attribute.data );\n\n\t\t\t}\n\n\t\t\treturn properties.get( attribute );\n\n\t\t}\n\n\t\tfunction getWireframeAttribute( geometry ) {\n\n\t\t\tvar property = properties.get( geometry );\n\n\t\t\tif ( property.wireframe !== undefined ) {\n\n\t\t\t\treturn property.wireframe;\n\n\t\t\t}\n\n\t\t\tvar indices = [];\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar attributes = geometry.attributes;\n\n\t\t\t// console.time( 'wireframe' );\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tvar array = index.array;\n\n\t\t\t\tfor ( var i = 0, l = array.length; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = array[ i + 0 ];\n\t\t\t\t\tvar b = array[ i + 1 ];\n\t\t\t\t\tvar c = array[ i + 2 ];\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar array = attributes.position.array;\n\n\t\t\t\tfor ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {\n\n\t\t\t\t\tvar a = i + 0;\n\t\t\t\t\tvar b = i + 1;\n\t\t\t\t\tvar c = i + 2;\n\n\t\t\t\t\tindices.push( a, b, b, c, c, a );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// console.timeEnd( 'wireframe' );\n\n\t\t\tvar attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );\n\n\t\t\tupdateAttribute( attribute, gl.ELEMENT_ARRAY_BUFFER );\n\n\t\t\tproperty.wireframe = attribute;\n\n\t\t\treturn attribute;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tgetAttributeBuffer: getAttributeBuffer,\n\t\t\tgetAttributeProperties: getAttributeProperties,\n\t\t\tgetWireframeAttribute: getWireframeAttribute,\n\n\t\t\tupdate: update\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, info ) {\n\n\t\tvar _infoMemory = info.memory;\n\t\tvar _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext );\n\n\t\t//\n\n\t\tfunction clampToMaxSize( image, maxSize ) {\n\n\t\t\tif ( image.width > maxSize || image.height > maxSize ) {\n\n\t\t\t\t// Warning: Scaling through the canvas will only work with images that use\n\t\t\t\t// premultiplied alpha.\n\n\t\t\t\tvar scale = maxSize / Math.max( image.width, image.height );\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = Math.floor( image.width * scale );\n\t\t\t\tcanvas.height = Math.floor( image.height * scale );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction isPowerOfTwo( image ) {\n\n\t\t\treturn _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );\n\n\t\t}\n\n\t\tfunction makePowerOfTwo( image ) {\n\n\t\t\tif ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {\n\n\t\t\t\tvar canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\t\t\tcanvas.width = _Math.nearestPowerOfTwo( image.width );\n\t\t\t\tcanvas.height = _Math.nearestPowerOfTwo( image.height );\n\n\t\t\t\tvar context = canvas.getContext( '2d' );\n\t\t\t\tcontext.drawImage( image, 0, 0, canvas.width, canvas.height );\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );\n\n\t\t\t\treturn canvas;\n\n\t\t\t}\n\n\t\t\treturn image;\n\n\t\t}\n\n\t\tfunction textureNeedsPowerOfTwo( texture ) {\n\n\t\t\treturn ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||\n\t\t\t\t( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );\n\n\t\t}\n\n\t\t// Fallback filters for non-power-of-2 textures\n\n\t\tfunction filterFallback( f ) {\n\n\t\t\tif ( f === NearestFilter || f === NearestMipMapNearestFilter || f === NearestMipMapLinearFilter ) {\n\n\t\t\t\treturn _gl.NEAREST;\n\n\t\t\t}\n\n\t\t\treturn _gl.LINEAR;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction onTextureDispose( event ) {\n\n\t\t\tvar texture = event.target;\n\n\t\t\ttexture.removeEventListener( 'dispose', onTextureDispose );\n\n\t\t\tdeallocateTexture( texture );\n\n\t\t\t_infoMemory.textures --;\n\n\n\t\t}\n\n\t\tfunction onRenderTargetDispose( event ) {\n\n\t\t\tvar renderTarget = event.target;\n\n\t\t\trenderTarget.removeEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\tdeallocateRenderTarget( renderTarget );\n\n\t\t\t_infoMemory.textures --;\n\n\t\t}\n\n\t\t//\n\n\t\tfunction deallocateTexture( texture ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image && textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t// cube texture\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__image__webglTextureCube );\n\n\t\t\t} else {\n\n\t\t\t\t// 2D texture\n\n\t\t\t\tif ( textureProperties.__webglInit === undefined ) return;\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\t// remove all webgl properties\n\t\t\tproperties.delete( texture );\n\n\t\t}\n\n\t\tfunction deallocateRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\tif ( ! renderTarget ) return;\n\n\t\t\tif ( textureProperties.__webglTexture !== undefined ) {\n\n\t\t\t\t_gl.deleteTexture( textureProperties.__webglTexture );\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\trenderTarget.depthTexture.dispose();\n\n\t\t\t}\n\n\t\t\tif ( renderTarget.isWebGLRenderTargetCube ) {\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );\n\t\t\t\tif ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );\n\n\t\t\t}\n\n\t\t\tproperties.delete( renderTarget.texture );\n\t\t\tproperties.delete( renderTarget );\n\n\t\t}\n\n\t\t//\n\n\n\n\t\tfunction setTexture2D( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\tvar image = texture.image;\n\n\t\t\t\tif ( image === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );\n\n\t\t\t\t} else if ( image.complete === false ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tuploadTexture( textureProperties, texture, slot );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureCube( texture, slot ) {\n\n\t\t\tvar textureProperties = properties.get( texture );\n\n\t\t\tif ( texture.image.length === 6 ) {\n\n\t\t\t\tif ( texture.version > 0 && textureProperties.__version !== texture.version ) {\n\n\t\t\t\t\tif ( ! textureProperties.__image__webglTextureCube ) {\n\n\t\t\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\t\t\ttextureProperties.__image__webglTextureCube = _gl.createTexture();\n\n\t\t\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\n\t\t\t\t\tvar isCompressed = ( texture && texture.isCompressedTexture );\n\t\t\t\t\tvar isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );\n\n\t\t\t\t\tvar cubeImage = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed && ! isDataTexture ) {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tcubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar image = cubeImage[ 0 ],\n\t\t\t\t\tisPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\tif ( ! isCompressed ) {\n\n\t\t\t\t\t\t\tif ( isDataTexture ) {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar mipmap, mipmaps = cubeImage[ i ].mipmaps;\n\n\t\t\t\t\t\t\tfor ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\t\t\tmipmap = mipmaps[ j ];\n\n\t\t\t\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()\" );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) {\n\n\t\t\t\t\t\t_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setTextureCubeDynamic( texture, slot ) {\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );\n\n\t\t}\n\n\t\tfunction setTextureParameters( textureType, texture, isPowerOfTwoImage ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( isPowerOfTwoImage ) {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );\n\n\t\t\t} else {\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );\n\n\t\t\t\tif ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );\n\n\t\t\t\t}\n\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );\n\t\t\t\t_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );\n\n\t\t\t\tif ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\textension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension ) {\n\n\t\t\t\tif ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;\n\t\t\t\tif ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;\n\n\t\t\t\tif ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {\n\n\t\t\t\t\t_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );\n\t\t\t\t\tproperties.get( texture ).__currentAnisotropy = texture.anisotropy;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction uploadTexture( textureProperties, texture, slot ) {\n\n\t\t\tif ( textureProperties.__webglInit === undefined ) {\n\n\t\t\t\ttextureProperties.__webglInit = true;\n\n\t\t\t\ttexture.addEventListener( 'dispose', onTextureDispose );\n\n\t\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t\t_infoMemory.textures ++;\n\n\t\t\t}\n\n\t\t\tstate.activeTexture( _gl.TEXTURE0 + slot );\n\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\n\t\t\t_gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );\n\t\t\t_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );\n\n\t\t\tvar image = clampToMaxSize( texture.image, capabilities.maxTextureSize );\n\n\t\t\tif ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {\n\n\t\t\t\timage = makePowerOfTwo( image );\n\n\t\t\t}\n\n\t\t\tvar isPowerOfTwoImage = isPowerOfTwo( image ),\n\t\t\tglFormat = paramThreeToGL( texture.format ),\n\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\tsetTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );\n\n\t\t\tvar mipmap, mipmaps = texture.mipmaps;\n\n\t\t\tif ( texture.isDepthTexture ) {\n\n\t\t\t\t// populate depth texture with dummy data\n\n\t\t\t\tvar internalFormat = _gl.DEPTH_COMPONENT;\n\n\t\t\t\tif ( texture.type === FloatType ) {\n\n\t\t\t\t\tif ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT32F;\n\n\t\t\t\t} else if ( _isWebGL2 ) {\n\n\t\t\t\t\t// WebGL 2.0 requires signed internalformat for glTexImage2D\n\t\t\t\t\tinternalFormat = _gl.DEPTH_COMPONENT16;\n\n\t\t\t\t}\n\n\t\t\t\tif ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedShortType;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Depth stencil textures need the DEPTH_STENCIL internal format\n\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\tif ( texture.format === DepthStencilFormat ) {\n\n\t\t\t\t\tinternalFormat = _gl.DEPTH_STENCIL;\n\n\t\t\t\t\t// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are\n\t\t\t\t\t// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.\n\t\t\t\t\t// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)\n\t\t\t\t\tif ( texture.type !== UnsignedInt248Type ) {\n\n\t\t\t\t\t console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );\n\n\t\t\t\t\t\ttexture.type = UnsignedInt248Type;\n\t\t\t\t\t\tglType = paramThreeToGL( texture.type );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );\n\n\t\t\t} else if ( texture.isDataTexture ) {\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );\n\n\t\t\t\t}\n\n\t\t\t} else if ( texture.isCompressedTexture ) {\n\n\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\tmipmap = mipmaps[ i ];\n\n\t\t\t\t\tif ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {\n\n\t\t\t\t\t\tif ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {\n\n\t\t\t\t\t\t\tstate.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()\" );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// regular Texture (image, video, canvas)\n\n\t\t\t\t// use manually created mipmaps if available\n\t\t\t\t// if there are no manual mipmaps\n\t\t\t\t// set 0 level mipmap and then use GL to generate other mipmap levels\n\n\t\t\t\tif ( mipmaps.length > 0 && isPowerOfTwoImage ) {\n\n\t\t\t\t\tfor ( var i = 0, il = mipmaps.length; i < il; i ++ ) {\n\n\t\t\t\t\t\tmipmap = mipmaps[ i ];\n\t\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.generateMipmaps = false;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstate.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\n\t\t\ttextureProperties.__version = texture.version;\n\n\t\t\tif ( texture.onUpdate ) texture.onUpdate( texture );\n\n\t\t}\n\n\t\t// Render targets\n\n\t\t// Setup storage for target texture and bind it to correct framebuffer\n\t\tfunction setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {\n\n\t\t\tvar glFormat = paramThreeToGL( renderTarget.texture.format );\n\t\t\tvar glType = paramThreeToGL( renderTarget.texture.type );\n\t\t\tstate.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Setup storage for internal depth/stencil buffers and bind to correct framebuffer\n\t\tfunction setupRenderBufferStorage( renderbuffer, renderTarget ) {\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\tif ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {\n\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );\n\t\t\t\t_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );\n\n\t\t\t} else {\n\n\t\t\t\t// FIXME: We don't support !depth !stencil\n\t\t\t\t_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );\n\n\t\t\t}\n\n\t\t\t_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );\n\n\t\t}\n\n\t\t// Setup resources for a Depth Texture for a FBO (needs an extension)\n\t\tfunction setupDepthTexture( framebuffer, renderTarget ) {\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tif ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\tif ( !( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {\n\n\t\t\t\tthrow new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');\n\n\t\t\t}\n\n\t\t\t// upload an empty depth texture with framebuffer size\n\t\t\tif ( !properties.get( renderTarget.depthTexture ).__webglTexture ||\n\t\t\t\t\trenderTarget.depthTexture.image.width !== renderTarget.width ||\n\t\t\t\t\trenderTarget.depthTexture.image.height !== renderTarget.height ) {\n\t\t\t\trenderTarget.depthTexture.image.width = renderTarget.width;\n\t\t\t\trenderTarget.depthTexture.image.height = renderTarget.height;\n\t\t\t\trenderTarget.depthTexture.needsUpdate = true;\n\t\t\t}\n\n\t\t\tsetTexture2D( renderTarget.depthTexture, 0 );\n\n\t\t\tvar webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;\n\n\t\t\tif ( renderTarget.depthTexture.format === DepthFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {\n\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );\n\n\t\t\t} else {\n\n\t\t\t\tthrow new Error('Unknown depthTexture format')\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Setup GL resources for a non-texture depth buffer\n\t\tfunction setupDepthRenderbuffer( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\n\t\t\tif ( renderTarget.depthTexture ) {\n\n\t\t\t\tif ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');\n\n\t\t\t\tsetupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );\n\n\t\t\t} else {\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = [];\n\n\t\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );\n\t\t\t\t\t\trenderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();\n\t\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );\n\t\t\t\t\trenderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();\n\t\t\t\t\tsetupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );\n\n\t\t}\n\n\t\t// Set up GL resources for the render target\n\t\tfunction setupRenderTarget( renderTarget ) {\n\n\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\n\t\t\trenderTarget.addEventListener( 'dispose', onRenderTargetDispose );\n\n\t\t\ttextureProperties.__webglTexture = _gl.createTexture();\n\n\t\t\t_infoMemory.textures ++;\n\n\t\t\tvar isCube = ( renderTarget.isWebGLRenderTargetCube === true );\n\t\t\tvar isTargetPowerOfTwo = isPowerOfTwo( renderTarget );\n\n\t\t\t// Setup framebuffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = [];\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\trenderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();\n\n\t\t\t}\n\n\t\t\t// Setup color buffer\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );\n\n\t\t\t\tfor ( var i = 0; i < 6; i ++ ) {\n\n\t\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );\n\n\t\t\t\t}\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_CUBE_MAP, null );\n\n\t\t\t} else {\n\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );\n\t\t\t\tsetTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );\n\t\t\t\tsetupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );\n\n\t\t\t\tif ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );\n\t\t\t\tstate.bindTexture( _gl.TEXTURE_2D, null );\n\n\t\t\t}\n\n\t\t\t// Setup depth and stencil buffers\n\n\t\t\tif ( renderTarget.depthBuffer ) {\n\n\t\t\t\tsetupDepthRenderbuffer( renderTarget );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction updateRenderTargetMipmap( renderTarget ) {\n\n\t\t\tvar texture = renderTarget.texture;\n\n\t\t\tif ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&\n\t\t\t\t\ttexture.minFilter !== NearestFilter &&\n\t\t\t\t\ttexture.minFilter !== LinearFilter ) {\n\n\t\t\t\tvar target = (renderTarget && renderTarget.isWebGLRenderTargetCube) ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;\n\t\t\t\tvar webglTexture = properties.get( texture ).__webglTexture;\n\n\t\t\t\tstate.bindTexture( target, webglTexture );\n\t\t\t\t_gl.generateMipmap( target );\n\t\t\t\tstate.bindTexture( target, null );\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setTexture2D = setTexture2D;\n\t\tthis.setTextureCube = setTextureCube;\n\t\tthis.setTextureCubeDynamic = setTextureCubeDynamic;\n\t\tthis.setupRenderTarget = setupRenderTarget;\n\t\tthis.updateRenderTargetMipmap = updateRenderTargetMipmap;\n\n\t}\n\n\t/**\n\t * @author fordacious / fordacious.github.io\n\t */\n\n\tfunction WebGLProperties() {\n\n\t\tvar properties = {};\n\n\t\treturn {\n\n\t\t\tget: function ( object ) {\n\n\t\t\t\tvar uuid = object.uuid;\n\t\t\t\tvar map = properties[ uuid ];\n\n\t\t\t\tif ( map === undefined ) {\n\n\t\t\t\t\tmap = {};\n\t\t\t\t\tproperties[ uuid ] = map;\n\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\n\t\t\t},\n\n\t\t\tdelete: function ( object ) {\n\n\t\t\t\tdelete properties[ object.uuid ];\n\n\t\t\t},\n\n\t\t\tclear: function () {\n\n\t\t\t\tproperties = {};\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLState( gl, extensions, paramThreeToGL ) {\n\n\t\tfunction ColorBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar color = new Vector4();\n\t\t\tvar currentColorMask = null;\n\t\t\tvar currentColorClear = new Vector4();\n\n\t\t\treturn {\n\n\t\t\t\tsetMask: function ( colorMask ) {\n\n\t\t\t\t\tif ( currentColorMask !== colorMask && ! locked ) {\n\n\t\t\t\t\t\tgl.colorMask( colorMask, colorMask, colorMask, colorMask );\n\t\t\t\t\t\tcurrentColorMask = colorMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( r, g, b, a, premultipliedAlpha ) {\n\n\t\t\t\t\tif ( premultipliedAlpha === true ) {\n\n\t\t\t\t\t\tr *= a; g *= a; b *= a;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tcolor.set( r, g, b, a );\n\n\t\t\t\t\tif ( currentColorClear.equals( color ) === false ) {\n\n\t\t\t\t\t\tgl.clearColor( r, g, b, a );\n\t\t\t\t\t\tcurrentColorClear.copy( color );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentColorMask = null;\n\t\t\t\t\tcurrentColorClear.set( 0, 0, 0, 1 );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction DepthBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentDepthMask = null;\n\t\t\tvar currentDepthFunc = null;\n\t\t\tvar currentDepthClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( depthTest ) {\n\n\t\t\t\t\tif ( depthTest ) {\n\n\t\t\t\t\t\tenable( gl.DEPTH_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.DEPTH_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( depthMask ) {\n\n\t\t\t\t\tif ( currentDepthMask !== depthMask && ! locked ) {\n\n\t\t\t\t\t\tgl.depthMask( depthMask );\n\t\t\t\t\t\tcurrentDepthMask = depthMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( depthFunc ) {\n\n\t\t\t\t\tif ( currentDepthFunc !== depthFunc ) {\n\n\t\t\t\t\t\tif ( depthFunc ) {\n\n\t\t\t\t\t\t\tswitch ( depthFunc ) {\n\n\t\t\t\t\t\t\t\tcase NeverDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NEVER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase AlwaysDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.ALWAYS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LESS );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase LessEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase EqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.EQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase GreaterDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.GREATER );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase NotEqualDepth:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.NOTEQUAL );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tgl.depthFunc( gl.LEQUAL );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrentDepthFunc = depthFunc;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( depth ) {\n\n\t\t\t\t\tif ( currentDepthClear !== depth ) {\n\n\t\t\t\t\t\tgl.clearDepth( depth );\n\t\t\t\t\t\tcurrentDepthClear = depth;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentDepthMask = null;\n\t\t\t\t\tcurrentDepthFunc = null;\n\t\t\t\t\tcurrentDepthClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\tfunction StencilBuffer() {\n\n\t\t\tvar locked = false;\n\n\t\t\tvar currentStencilMask = null;\n\t\t\tvar currentStencilFunc = null;\n\t\t\tvar currentStencilRef = null;\n\t\t\tvar currentStencilFuncMask = null;\n\t\t\tvar currentStencilFail = null;\n\t\t\tvar currentStencilZFail = null;\n\t\t\tvar currentStencilZPass = null;\n\t\t\tvar currentStencilClear = null;\n\n\t\t\treturn {\n\n\t\t\t\tsetTest: function ( stencilTest ) {\n\n\t\t\t\t\tif ( stencilTest ) {\n\n\t\t\t\t\t\tenable( gl.STENCIL_TEST );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tdisable( gl.STENCIL_TEST );\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetMask: function ( stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilMask !== stencilMask && ! locked ) {\n\n\t\t\t\t\t\tgl.stencilMask( stencilMask );\n\t\t\t\t\t\tcurrentStencilMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetFunc: function ( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\t\t\tif ( currentStencilFunc !== stencilFunc ||\n\t\t\t\t\t currentStencilRef \t!== stencilRef \t||\n\t\t\t\t\t currentStencilFuncMask !== stencilMask ) {\n\n\t\t\t\t\t\tgl.stencilFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t\t\t\t\tcurrentStencilFunc = stencilFunc;\n\t\t\t\t\t\tcurrentStencilRef = stencilRef;\n\t\t\t\t\t\tcurrentStencilFuncMask = stencilMask;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetOp: function ( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\t\t\tif ( currentStencilFail\t !== stencilFail \t||\n\t\t\t\t\t currentStencilZFail !== stencilZFail ||\n\t\t\t\t\t currentStencilZPass !== stencilZPass ) {\n\n\t\t\t\t\t\tgl.stencilOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t\t\t\t\tcurrentStencilFail = stencilFail;\n\t\t\t\t\t\tcurrentStencilZFail = stencilZFail;\n\t\t\t\t\t\tcurrentStencilZPass = stencilZPass;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tsetLocked: function ( lock ) {\n\n\t\t\t\t\tlocked = lock;\n\n\t\t\t\t},\n\n\t\t\t\tsetClear: function ( stencil ) {\n\n\t\t\t\t\tif ( currentStencilClear !== stencil ) {\n\n\t\t\t\t\t\tgl.clearStencil( stencil );\n\t\t\t\t\t\tcurrentStencilClear = stencil;\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\treset: function () {\n\n\t\t\t\t\tlocked = false;\n\n\t\t\t\t\tcurrentStencilMask = null;\n\t\t\t\t\tcurrentStencilFunc = null;\n\t\t\t\t\tcurrentStencilRef = null;\n\t\t\t\t\tcurrentStencilFuncMask = null;\n\t\t\t\t\tcurrentStencilFail = null;\n\t\t\t\t\tcurrentStencilZFail = null;\n\t\t\t\t\tcurrentStencilZPass = null;\n\t\t\t\t\tcurrentStencilClear = null;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}\n\n\t\t//\n\n\t\tvar colorBuffer = new ColorBuffer();\n\t\tvar depthBuffer = new DepthBuffer();\n\t\tvar stencilBuffer = new StencilBuffer();\n\n\t\tvar maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar newAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar enabledAttributes = new Uint8Array( maxVertexAttributes );\n\t\tvar attributeDivisors = new Uint8Array( maxVertexAttributes );\n\n\t\tvar capabilities = {};\n\n\t\tvar compressedTextureFormats = null;\n\n\t\tvar currentBlending = null;\n\t\tvar currentBlendEquation = null;\n\t\tvar currentBlendSrc = null;\n\t\tvar currentBlendDst = null;\n\t\tvar currentBlendEquationAlpha = null;\n\t\tvar currentBlendSrcAlpha = null;\n\t\tvar currentBlendDstAlpha = null;\n\t\tvar currentPremultipledAlpha = false;\n\n\t\tvar currentFlipSided = null;\n\t\tvar currentCullFace = null;\n\n\t\tvar currentLineWidth = null;\n\n\t\tvar currentPolygonOffsetFactor = null;\n\t\tvar currentPolygonOffsetUnits = null;\n\n\t\tvar currentScissorTest = null;\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\n\t\tvar version = parseFloat( /^WebGL\\ ([0-9])/.exec( gl.getParameter( gl.VERSION ) )[ 1 ] );\n\t\tvar lineWidthAvailable = parseFloat( version ) >= 1.0;\n\n\t\tvar currentTextureSlot = null;\n\t\tvar currentBoundTextures = {};\n\n\t\tvar currentScissor = new Vector4();\n\t\tvar currentViewport = new Vector4();\n\n\t\tfunction createTexture( type, target, count ) {\n\n\t\t\tvar data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.\n\t\t\tvar texture = gl.createTexture();\n\n\t\t\tgl.bindTexture( type, texture );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST );\n\t\t\tgl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST );\n\n\t\t\tfor ( var i = 0; i < count; i ++ ) {\n\n\t\t\t\tgl.texImage2D( target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t\tvar emptyTextures = {};\n\t\temptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 );\n\t\temptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 );\n\n\t\t//\n\n\t\tfunction init() {\n\n\t\t\tcolorBuffer.setClear( 0, 0, 0, 1 );\n\t\t\tdepthBuffer.setClear( 1 );\n\t\t\tstencilBuffer.setClear( 0 );\n\n\t\t\tenable( gl.DEPTH_TEST );\n\t\t\tsetDepthFunc( LessEqualDepth );\n\n\t\t\tsetFlipSided( false );\n\t\t\tsetCullFace( CullFaceBack );\n\t\t\tenable( gl.CULL_FACE );\n\n\t\t\tenable( gl.BLEND );\n\t\t\tsetBlending( NormalBlending );\n\n\t\t}\n\n\t\tfunction initAttributes() {\n\n\t\t\tfor ( var i = 0, l = newAttributes.length; i < l; i ++ ) {\n\n\t\t\t\tnewAttributes[ i ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttribute( attribute ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== 0 ) {\n\n\t\t\t\tvar extension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, 0 );\n\t\t\t\tattributeDivisors[ attribute ] = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enableAttributeAndDivisor( attribute, meshPerAttribute, extension ) {\n\n\t\t\tnewAttributes[ attribute ] = 1;\n\n\t\t\tif ( enabledAttributes[ attribute ] === 0 ) {\n\n\t\t\t\tgl.enableVertexAttribArray( attribute );\n\t\t\t\tenabledAttributes[ attribute ] = 1;\n\n\t\t\t}\n\n\t\t\tif ( attributeDivisors[ attribute ] !== meshPerAttribute ) {\n\n\t\t\t\textension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );\n\t\t\t\tattributeDivisors[ attribute ] = meshPerAttribute;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disableUnusedAttributes() {\n\n\t\t\tfor ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] !== newAttributes[ i ] ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction enable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== true ) {\n\n\t\t\t\tgl.enable( id );\n\t\t\t\tcapabilities[ id ] = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction disable( id ) {\n\n\t\t\tif ( capabilities[ id ] !== false ) {\n\n\t\t\t\tgl.disable( id );\n\t\t\t\tcapabilities[ id ] = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getCompressedTextureFormats() {\n\n\t\t\tif ( compressedTextureFormats === null ) {\n\n\t\t\t\tcompressedTextureFormats = [];\n\n\t\t\t\tif ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||\n\t\t\t\t extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {\n\n\t\t\t\t\tvar formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );\n\n\t\t\t\t\tfor ( var i = 0; i < formats.length; i ++ ) {\n\n\t\t\t\t\t\tcompressedTextureFormats.push( formats[ i ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn compressedTextureFormats;\n\n\t\t}\n\n\t\tfunction setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {\n\n\t\t\tif ( blending !== NoBlending ) {\n\n\t\t\t\tenable( gl.BLEND );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.BLEND );\n\n\t\t\t}\n\n\t\t\tif ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {\n\n\t\t\t\tif ( blending === AdditiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.SRC_ALPHA, gl.ONE );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === SubtractiveBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( blending === MultiplyBlending ) {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquation( gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFunc( gl.ZERO, gl.SRC_COLOR );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( premultipliedAlpha ) {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );\n\t\t\t\t\t\tgl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tcurrentBlending = blending;\n\t\t\t\tcurrentPremultipledAlpha = premultipliedAlpha;\n\n\t\t\t}\n\n\t\t\tif ( blending === CustomBlending ) {\n\n\t\t\t\tblendEquationAlpha = blendEquationAlpha || blendEquation;\n\t\t\t\tblendSrcAlpha = blendSrcAlpha || blendSrc;\n\t\t\t\tblendDstAlpha = blendDstAlpha || blendDst;\n\n\t\t\t\tif ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {\n\n\t\t\t\t\tgl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );\n\n\t\t\t\t\tcurrentBlendEquation = blendEquation;\n\t\t\t\t\tcurrentBlendEquationAlpha = blendEquationAlpha;\n\n\t\t\t\t}\n\n\t\t\t\tif ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {\n\n\t\t\t\t\tgl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );\n\n\t\t\t\t\tcurrentBlendSrc = blendSrc;\n\t\t\t\t\tcurrentBlendDst = blendDst;\n\t\t\t\t\tcurrentBlendSrcAlpha = blendSrcAlpha;\n\t\t\t\t\tcurrentBlendDstAlpha = blendDstAlpha;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tcurrentBlendEquation = null;\n\t\t\t\tcurrentBlendSrc = null;\n\t\t\t\tcurrentBlendDst = null;\n\t\t\t\tcurrentBlendEquationAlpha = null;\n\t\t\t\tcurrentBlendSrcAlpha = null;\n\t\t\t\tcurrentBlendDstAlpha = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Deprecate\n\n\t\tfunction setColorWrite( colorWrite ) {\n\n\t\t\tcolorBuffer.setMask( colorWrite );\n\n\t\t}\n\n\t\tfunction setDepthTest( depthTest ) {\n\n\t\t\tdepthBuffer.setTest( depthTest );\n\n\t\t}\n\n\t\tfunction setDepthWrite( depthWrite ) {\n\n\t\t\tdepthBuffer.setMask( depthWrite );\n\n\t\t}\n\n\t\tfunction setDepthFunc( depthFunc ) {\n\n\t\t\tdepthBuffer.setFunc( depthFunc );\n\n\t\t}\n\n\t\tfunction setStencilTest( stencilTest ) {\n\n\t\t\tstencilBuffer.setTest( stencilTest );\n\n\t\t}\n\n\t\tfunction setStencilWrite( stencilWrite ) {\n\n\t\t\tstencilBuffer.setMask( stencilWrite );\n\n\t\t}\n\n\t\tfunction setStencilFunc( stencilFunc, stencilRef, stencilMask ) {\n\n\t\t\tstencilBuffer.setFunc( stencilFunc, stencilRef, stencilMask );\n\n\t\t}\n\n\t\tfunction setStencilOp( stencilFail, stencilZFail, stencilZPass ) {\n\n\t\t\tstencilBuffer.setOp( stencilFail, stencilZFail, stencilZPass );\n\n\t\t}\n\n\t\t//\n\n\t\tfunction setFlipSided( flipSided ) {\n\n\t\t\tif ( currentFlipSided !== flipSided ) {\n\n\t\t\t\tif ( flipSided ) {\n\n\t\t\t\t\tgl.frontFace( gl.CW );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tgl.frontFace( gl.CCW );\n\n\t\t\t\t}\n\n\t\t\t\tcurrentFlipSided = flipSided;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setCullFace( cullFace ) {\n\n\t\t\tif ( cullFace !== CullFaceNone ) {\n\n\t\t\t\tenable( gl.CULL_FACE );\n\n\t\t\t\tif ( cullFace !== currentCullFace ) {\n\n\t\t\t\t\tif ( cullFace === CullFaceBack ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.BACK );\n\n\t\t\t\t\t} else if ( cullFace === CullFaceFront ) {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tgl.cullFace( gl.FRONT_AND_BACK );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.CULL_FACE );\n\n\t\t\t}\n\n\t\t\tcurrentCullFace = cullFace;\n\n\t\t}\n\n\t\tfunction setLineWidth( width ) {\n\n\t\t\tif ( width !== currentLineWidth ) {\n\n\t\t\t\tif ( lineWidthAvailable ) gl.lineWidth( width );\n\n\t\t\t\tcurrentLineWidth = width;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction setPolygonOffset( polygonOffset, factor, units ) {\n\n\t\t\tif ( polygonOffset ) {\n\n\t\t\t\tenable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t\tif ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {\n\n\t\t\t\t\tgl.polygonOffset( factor, units );\n\n\t\t\t\t\tcurrentPolygonOffsetFactor = factor;\n\t\t\t\t\tcurrentPolygonOffsetUnits = units;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.POLYGON_OFFSET_FILL );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction getScissorTest() {\n\n\t\t\treturn currentScissorTest;\n\n\t\t}\n\n\t\tfunction setScissorTest( scissorTest ) {\n\n\t\t\tcurrentScissorTest = scissorTest;\n\n\t\t\tif ( scissorTest ) {\n\n\t\t\t\tenable( gl.SCISSOR_TEST );\n\n\t\t\t} else {\n\n\t\t\t\tdisable( gl.SCISSOR_TEST );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// texture\n\n\t\tfunction activeTexture( webglSlot ) {\n\n\t\t\tif ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;\n\n\t\t\tif ( currentTextureSlot !== webglSlot ) {\n\n\t\t\t\tgl.activeTexture( webglSlot );\n\t\t\t\tcurrentTextureSlot = webglSlot;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction bindTexture( webglType, webglTexture ) {\n\n\t\t\tif ( currentTextureSlot === null ) {\n\n\t\t\t\tactiveTexture();\n\n\t\t\t}\n\n\t\t\tvar boundTexture = currentBoundTextures[ currentTextureSlot ];\n\n\t\t\tif ( boundTexture === undefined ) {\n\n\t\t\t\tboundTexture = { type: undefined, texture: undefined };\n\t\t\t\tcurrentBoundTextures[ currentTextureSlot ] = boundTexture;\n\n\t\t\t}\n\n\t\t\tif ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {\n\n\t\t\t\tgl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );\n\n\t\t\t\tboundTexture.type = webglType;\n\t\t\t\tboundTexture.texture = webglTexture;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction compressedTexImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.compressedTexImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction texImage2D() {\n\n\t\t\ttry {\n\n\t\t\t\tgl.texImage2D.apply( gl, arguments );\n\n\t\t\t} catch ( error ) {\n\n\t\t\t\tconsole.error( error );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction scissor( scissor ) {\n\n\t\t\tif ( currentScissor.equals( scissor ) === false ) {\n\n\t\t\t\tgl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );\n\t\t\t\tcurrentScissor.copy( scissor );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction viewport( viewport ) {\n\n\t\t\tif ( currentViewport.equals( viewport ) === false ) {\n\n\t\t\t\tgl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );\n\t\t\t\tcurrentViewport.copy( viewport );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tfunction reset() {\n\n\t\t\tfor ( var i = 0; i < enabledAttributes.length; i ++ ) {\n\n\t\t\t\tif ( enabledAttributes[ i ] === 1 ) {\n\n\t\t\t\t\tgl.disableVertexAttribArray( i );\n\t\t\t\t\tenabledAttributes[ i ] = 0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tcapabilities = {};\n\n\t\t\tcompressedTextureFormats = null;\n\n\t\t\tcurrentTextureSlot = null;\n\t\t\tcurrentBoundTextures = {};\n\n\t\t\tcurrentBlending = null;\n\n\t\t\tcurrentFlipSided = null;\n\t\t\tcurrentCullFace = null;\n\n\t\t\tcolorBuffer.reset();\n\t\t\tdepthBuffer.reset();\n\t\t\tstencilBuffer.reset();\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tbuffers: {\n\t\t\t\tcolor: colorBuffer,\n\t\t\t\tdepth: depthBuffer,\n\t\t\t\tstencil: stencilBuffer\n\t\t\t},\n\n\t\t\tinit: init,\n\t\t\tinitAttributes: initAttributes,\n\t\t\tenableAttribute: enableAttribute,\n\t\t\tenableAttributeAndDivisor: enableAttributeAndDivisor,\n\t\t\tdisableUnusedAttributes: disableUnusedAttributes,\n\t\t\tenable: enable,\n\t\t\tdisable: disable,\n\t\t\tgetCompressedTextureFormats: getCompressedTextureFormats,\n\n\t\t\tsetBlending: setBlending,\n\n\t\t\tsetColorWrite: setColorWrite,\n\t\t\tsetDepthTest: setDepthTest,\n\t\t\tsetDepthWrite: setDepthWrite,\n\t\t\tsetDepthFunc: setDepthFunc,\n\t\t\tsetStencilTest: setStencilTest,\n\t\t\tsetStencilWrite: setStencilWrite,\n\t\t\tsetStencilFunc: setStencilFunc,\n\t\t\tsetStencilOp: setStencilOp,\n\n\t\t\tsetFlipSided: setFlipSided,\n\t\t\tsetCullFace: setCullFace,\n\n\t\t\tsetLineWidth: setLineWidth,\n\t\t\tsetPolygonOffset: setPolygonOffset,\n\n\t\t\tgetScissorTest: getScissorTest,\n\t\t\tsetScissorTest: setScissorTest,\n\n\t\t\tactiveTexture: activeTexture,\n\t\t\tbindTexture: bindTexture,\n\t\t\tcompressedTexImage2D: compressedTexImage2D,\n\t\t\ttexImage2D: texImage2D,\n\n\t\t\tscissor: scissor,\n\t\t\tviewport: viewport,\n\n\t\t\treset: reset\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLCapabilities( gl, extensions, parameters ) {\n\n\t\tvar maxAnisotropy;\n\n\t\tfunction getMaxAnisotropy() {\n\n\t\t\tif ( maxAnisotropy !== undefined ) return maxAnisotropy;\n\n\t\t\tvar extension = extensions.get( 'EXT_texture_filter_anisotropic' );\n\n\t\t\tif ( extension !== null ) {\n\n\t\t\t\tmaxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );\n\n\t\t\t} else {\n\n\t\t\t\tmaxAnisotropy = 0;\n\n\t\t\t}\n\n\t\t\treturn maxAnisotropy;\n\n\t\t}\n\n\t\tfunction getMaxPrecision( precision ) {\n\n\t\t\tif ( precision === 'highp' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'highp';\n\n\t\t\t\t}\n\n\t\t\t\tprecision = 'mediump';\n\n\t\t\t}\n\n\t\t\tif ( precision === 'mediump' ) {\n\n\t\t\t\tif ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&\n\t\t\t\t gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {\n\n\t\t\t\t\treturn 'mediump';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn 'lowp';\n\n\t\t}\n\n\t\tvar precision = parameters.precision !== undefined ? parameters.precision : 'highp';\n\t\tvar maxPrecision = getMaxPrecision( precision );\n\n\t\tif ( maxPrecision !== precision ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );\n\t\t\tprecision = maxPrecision;\n\n\t\t}\n\n\t\tvar logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true && !! extensions.get( 'EXT_frag_depth' );\n\n\t\tvar maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );\n\t\tvar maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );\n\t\tvar maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );\n\n\t\tvar maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );\n\t\tvar maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );\n\t\tvar maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );\n\t\tvar maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );\n\n\t\tvar vertexTextures = maxVertexTextures > 0;\n\t\tvar floatFragmentTextures = !! extensions.get( 'OES_texture_float' );\n\t\tvar floatVertexTextures = vertexTextures && floatFragmentTextures;\n\n\t\treturn {\n\n\t\t\tgetMaxAnisotropy: getMaxAnisotropy,\n\t\t\tgetMaxPrecision: getMaxPrecision,\n\n\t\t\tprecision: precision,\n\t\t\tlogarithmicDepthBuffer: logarithmicDepthBuffer,\n\n\t\t\tmaxTextures: maxTextures,\n\t\t\tmaxVertexTextures: maxVertexTextures,\n\t\t\tmaxTextureSize: maxTextureSize,\n\t\t\tmaxCubemapSize: maxCubemapSize,\n\n\t\t\tmaxAttributes: maxAttributes,\n\t\t\tmaxVertexUniforms: maxVertexUniforms,\n\t\t\tmaxVaryings: maxVaryings,\n\t\t\tmaxFragmentUniforms: maxFragmentUniforms,\n\n\t\t\tvertexTextures: vertexTextures,\n\t\t\tfloatFragmentTextures: floatFragmentTextures,\n\t\t\tfloatVertexTextures: floatVertexTextures\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction WebGLExtensions( gl ) {\n\n\t\tvar extensions = {};\n\n\t\treturn {\n\n\t\t\tget: function ( name ) {\n\n\t\t\t\tif ( extensions[ name ] !== undefined ) {\n\n\t\t\t\t\treturn extensions[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tvar extension;\n\n\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\tcase 'WEBGL_depth_texture':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'EXT_texture_filter_anisotropic':\n\t\t\t\t\t\textension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_s3tc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_pvrtc':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'WEBGL_compressed_texture_etc1':\n\t\t\t\t\t\textension = gl.getExtension( 'WEBGL_compressed_texture_etc1' );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\textension = gl.getExtension( name );\n\n\t\t\t\t}\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );\n\n\t\t\t\t}\n\n\t\t\t\textensions[ name ] = extension;\n\n\t\t\t\treturn extension;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction WebGLClipping() {\n\n\t\tvar scope = this,\n\n\t\t\tglobalState = null,\n\t\t\tnumGlobalPlanes = 0,\n\t\t\tlocalClippingEnabled = false,\n\t\t\trenderingShadows = false,\n\n\t\t\tplane = new Plane(),\n\t\t\tviewNormalMatrix = new Matrix3(),\n\n\t\t\tuniform = { value: null, needsUpdate: false };\n\n\t\tthis.uniform = uniform;\n\t\tthis.numPlanes = 0;\n\t\tthis.numIntersection = 0;\n\n\t\tthis.init = function( planes, enableLocalClipping, camera ) {\n\n\t\t\tvar enabled =\n\t\t\t\tplanes.length !== 0 ||\n\t\t\t\tenableLocalClipping ||\n\t\t\t\t// enable state of previous frame - the clipping code has to\n\t\t\t\t// run another frame in order to reset the state:\n\t\t\t\tnumGlobalPlanes !== 0 ||\n\t\t\t\tlocalClippingEnabled;\n\n\t\t\tlocalClippingEnabled = enableLocalClipping;\n\n\t\t\tglobalState = projectPlanes( planes, camera, 0 );\n\t\t\tnumGlobalPlanes = planes.length;\n\n\t\t\treturn enabled;\n\n\t\t};\n\n\t\tthis.beginShadows = function() {\n\n\t\t\trenderingShadows = true;\n\t\t\tprojectPlanes( null );\n\n\t\t};\n\n\t\tthis.endShadows = function() {\n\n\t\t\trenderingShadows = false;\n\t\t\tresetGlobalState();\n\n\t\t};\n\n\t\tthis.setState = function( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {\n\n\t\t\tif ( ! localClippingEnabled ||\n\t\t\t\t\tplanes === null || planes.length === 0 ||\n\t\t\t\t\trenderingShadows && ! clipShadows ) {\n\t\t\t\t// there's no local clipping\n\n\t\t\t\tif ( renderingShadows ) {\n\t\t\t\t\t// there's no global clipping\n\n\t\t\t\t\tprojectPlanes( null );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tresetGlobalState();\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar nGlobal = renderingShadows ? 0 : numGlobalPlanes,\n\t\t\t\t\tlGlobal = nGlobal * 4,\n\n\t\t\t\t\tdstArray = cache.clippingState || null;\n\n\t\t\t\tuniform.value = dstArray; // ensure unique state\n\n\t\t\t\tdstArray = projectPlanes( planes, camera, lGlobal, fromCache );\n\n\t\t\t\tfor ( var i = 0; i !== lGlobal; ++ i ) {\n\n\t\t\t\t\tdstArray[ i ] = globalState[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcache.clippingState = dstArray;\n\t\t\t\tthis.numIntersection = clipIntersection ? this.numPlanes : 0;\n\t\t\t\tthis.numPlanes += nGlobal;\n\n\t\t\t}\n\n\n\t\t};\n\n\t\tfunction resetGlobalState() {\n\n\t\t\tif ( uniform.value !== globalState ) {\n\n\t\t\t\tuniform.value = globalState;\n\t\t\t\tuniform.needsUpdate = numGlobalPlanes > 0;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = numGlobalPlanes;\n\t\t\tscope.numIntersection = 0;\n\n\t\t}\n\n\t\tfunction projectPlanes( planes, camera, dstOffset, skipTransform ) {\n\n\t\t\tvar nPlanes = planes !== null ? planes.length : 0,\n\t\t\t\tdstArray = null;\n\n\t\t\tif ( nPlanes !== 0 ) {\n\n\t\t\t\tdstArray = uniform.value;\n\n\t\t\t\tif ( skipTransform !== true || dstArray === null ) {\n\n\t\t\t\t\tvar flatSize = dstOffset + nPlanes * 4,\n\t\t\t\t\t\tviewMatrix = camera.matrixWorldInverse;\n\n\t\t\t\t\tviewNormalMatrix.getNormalMatrix( viewMatrix );\n\n\t\t\t\t\tif ( dstArray === null || dstArray.length < flatSize ) {\n\n\t\t\t\t\t\tdstArray = new Float32Array( flatSize );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0, i4 = dstOffset;\n\t\t\t\t\t\t\t\t\t\ti !== nPlanes; ++ i, i4 += 4 ) {\n\n\t\t\t\t\t\tplane.copy( planes[ i ] ).\n\t\t\t\t\t\t\t\tapplyMatrix4( viewMatrix, viewNormalMatrix );\n\n\t\t\t\t\t\tplane.normal.toArray( dstArray, i4 );\n\t\t\t\t\t\tdstArray[ i4 + 3 ] = plane.constant;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tuniform.value = dstArray;\n\t\t\t\tuniform.needsUpdate = true;\n\n\t\t\t}\n\n\t\t\tscope.numPlanes = nPlanes;\n\t\t\t\n\t\t\treturn dstArray;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author supereggbert / http://www.paulbrunt.co.uk/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author szimek / https://github.com/szimek/\n\t * @author tschw\n\t */\n\n\tfunction WebGLRenderer( parameters ) {\n\n\t\tconsole.log( 'THREE.WebGLRenderer', REVISION );\n\n\t\tparameters = parameters || {};\n\n\t\tvar _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),\n\t\t\t_context = parameters.context !== undefined ? parameters.context : null,\n\n\t\t\t_alpha = parameters.alpha !== undefined ? parameters.alpha : false,\n\t\t\t_depth = parameters.depth !== undefined ? parameters.depth : true,\n\t\t\t_stencil = parameters.stencil !== undefined ? parameters.stencil : true,\n\t\t\t_antialias = parameters.antialias !== undefined ? parameters.antialias : false,\n\t\t\t_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,\n\t\t\t_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;\n\n\t\tvar lights = [];\n\n\t\tvar opaqueObjects = [];\n\t\tvar opaqueObjectsLastIndex = - 1;\n\t\tvar transparentObjects = [];\n\t\tvar transparentObjectsLastIndex = - 1;\n\n\t\tvar morphInfluences = new Float32Array( 8 );\n\n\t\tvar sprites = [];\n\t\tvar lensFlares = [];\n\n\t\t// public properties\n\n\t\tthis.domElement = _canvas;\n\t\tthis.context = null;\n\n\t\t// clearing\n\n\t\tthis.autoClear = true;\n\t\tthis.autoClearColor = true;\n\t\tthis.autoClearDepth = true;\n\t\tthis.autoClearStencil = true;\n\n\t\t// scene graph\n\n\t\tthis.sortObjects = true;\n\n\t\t// user-defined clipping\n\n\t\tthis.clippingPlanes = [];\n\t\tthis.localClippingEnabled = false;\n\n\t\t// physically based shading\n\n\t\tthis.gammaFactor = 2.0;\t// for backwards compatibility\n\t\tthis.gammaInput = false;\n\t\tthis.gammaOutput = false;\n\n\t\t// physical lights\n\n\t\tthis.physicallyCorrectLights = false;\n\n\t\t// tone mapping\n\n\t\tthis.toneMapping = LinearToneMapping;\n\t\tthis.toneMappingExposure = 1.0;\n\t\tthis.toneMappingWhitePoint = 1.0;\n\n\t\t// morphs\n\n\t\tthis.maxMorphTargets = 8;\n\t\tthis.maxMorphNormals = 4;\n\n\t\t// internal properties\n\n\t\tvar _this = this,\n\n\t\t\t// internal state cache\n\n\t\t\t_currentProgram = null,\n\t\t\t_currentRenderTarget = null,\n\t\t\t_currentFramebuffer = null,\n\t\t\t_currentMaterialId = - 1,\n\t\t\t_currentGeometryProgram = '',\n\t\t\t_currentCamera = null,\n\n\t\t\t_currentScissor = new Vector4(),\n\t\t\t_currentScissorTest = null,\n\n\t\t\t_currentViewport = new Vector4(),\n\n\t\t\t//\n\n\t\t\t_usedTextureUnits = 0,\n\n\t\t\t//\n\n\t\t\t_clearColor = new Color( 0x000000 ),\n\t\t\t_clearAlpha = 0,\n\n\t\t\t_width = _canvas.width,\n\t\t\t_height = _canvas.height,\n\n\t\t\t_pixelRatio = 1,\n\n\t\t\t_scissor = new Vector4( 0, 0, _width, _height ),\n\t\t\t_scissorTest = false,\n\n\t\t\t_viewport = new Vector4( 0, 0, _width, _height ),\n\n\t\t\t// frustum\n\n\t\t\t_frustum = new Frustum(),\n\n\t\t\t// clipping\n\n\t\t\t_clipping = new WebGLClipping(),\n\t\t\t_clippingEnabled = false,\n\t\t\t_localClippingEnabled = false,\n\n\t\t\t_sphere = new Sphere(),\n\n\t\t\t// camera matrices cache\n\n\t\t\t_projScreenMatrix = new Matrix4(),\n\n\t\t\t_vector3 = new Vector3(),\n\t\t\t_matrix4 = new Matrix4(),\n\t\t\t_matrix42 = new Matrix4(),\n\n\t\t\t// light arrays cache\n\n\t\t\t_lights = {\n\n\t\t\t\thash: '',\n\n\t\t\tambient: [ 0, 0, 0 ],\n\t\t\tdirectional: [],\n\t\t\tdirectionalShadowMap: [],\n\t\t\tdirectionalShadowMatrix: [],\n\t\t\tspot: [],\n\t\t\tspotShadowMap: [],\n\t\t\tspotShadowMatrix: [],\n\t\t\trectArea: [],\n\t\t\tpoint: [],\n\t\t\tpointShadowMap: [],\n\t\t\tpointShadowMatrix: [],\n\t\t\themi: [],\n\n\t\t\t\tshadows: []\n\n\t\t\t},\n\n\t\t\t// info\n\n\t\t\t_infoRender = {\n\n\t\t\t\tcalls: 0,\n\t\t\t\tvertices: 0,\n\t\t\t\tfaces: 0,\n\t\t\t\tpoints: 0\n\n\t\t\t};\n\n\t\tthis.info = {\n\n\t\t\trender: _infoRender,\n\t\t\tmemory: {\n\n\t\t\t\tgeometries: 0,\n\t\t\t\ttextures: 0\n\n\t\t\t},\n\t\t\tprograms: null\n\n\t\t};\n\n\n\t\t// initialize\n\n\t\tvar _gl;\n\n\t\ttry {\n\n\t\t\tvar attributes = {\n\t\t\t\talpha: _alpha,\n\t\t\t\tdepth: _depth,\n\t\t\t\tstencil: _stencil,\n\t\t\t\tantialias: _antialias,\n\t\t\t\tpremultipliedAlpha: _premultipliedAlpha,\n\t\t\t\tpreserveDrawingBuffer: _preserveDrawingBuffer\n\t\t\t};\n\n\t\t\t_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );\n\n\t\t\tif ( _gl === null ) {\n\n\t\t\t\tif ( _canvas.getContext( 'webgl' ) !== null ) {\n\n\t\t\t\t\tthrow 'Error creating WebGL context with your selected attributes.';\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow 'Error creating WebGL context.';\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Some experimental-webgl implementations do not have getShaderPrecisionFormat\n\n\t\t\tif ( _gl.getShaderPrecisionFormat === undefined ) {\n\n\t\t\t\t_gl.getShaderPrecisionFormat = function () {\n\n\t\t\t\t\treturn { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };\n\n\t\t\t\t};\n\n\t\t\t}\n\n\t\t\t_canvas.addEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t} catch ( error ) {\n\n\t\t\tconsole.error( 'THREE.WebGLRenderer: ' + error );\n\n\t\t}\n\n\t\tvar extensions = new WebGLExtensions( _gl );\n\n\t\textensions.get( 'WEBGL_depth_texture' );\n\t\textensions.get( 'OES_texture_float' );\n\t\textensions.get( 'OES_texture_float_linear' );\n\t\textensions.get( 'OES_texture_half_float' );\n\t\textensions.get( 'OES_texture_half_float_linear' );\n\t\textensions.get( 'OES_standard_derivatives' );\n\t\textensions.get( 'ANGLE_instanced_arrays' );\n\n\t\tif ( extensions.get( 'OES_element_index_uint' ) ) {\n\n\t\t\tBufferGeometry.MaxIndex = 4294967296;\n\n\t\t}\n\n\t\tvar capabilities = new WebGLCapabilities( _gl, extensions, parameters );\n\n\t\tvar state = new WebGLState( _gl, extensions, paramThreeToGL );\n\t\tvar properties = new WebGLProperties();\n\t\tvar textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );\n\t\tvar objects = new WebGLObjects( _gl, properties, this.info );\n\t\tvar programCache = new WebGLPrograms( this, capabilities );\n\t\tvar lightCache = new WebGLLights();\n\n\t\tthis.info.programs = programCache.programs;\n\n\t\tvar bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );\n\t\tvar indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );\n\n\t\t//\n\n\t\tvar backgroundPlaneCamera, backgroundPlaneMesh;\n\t\tvar backgroundBoxCamera, backgroundBoxMesh;\n\n\t\t//\n\n\t\tfunction getTargetPixelRatio() {\n\n\t\t\treturn _currentRenderTarget === null ? _pixelRatio : 1;\n\n\t\t}\n\n\t\tfunction setDefaultGLState() {\n\n\t\t\tstate.init();\n\n\t\t\tstate.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );\n\t\t\tstate.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t}\n\n\t\tfunction resetGLState() {\n\n\t\t\t_currentProgram = null;\n\t\t\t_currentCamera = null;\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\n\t\t\tstate.reset();\n\n\t\t}\n\n\t\tsetDefaultGLState();\n\n\t\tthis.context = _gl;\n\t\tthis.capabilities = capabilities;\n\t\tthis.extensions = extensions;\n\t\tthis.properties = properties;\n\t\tthis.state = state;\n\n\t\t// shadow map\n\n\t\tvar shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );\n\n\t\tthis.shadowMap = shadowMap;\n\n\n\t\t// Plugins\n\n\t\tvar spritePlugin = new SpritePlugin( this, sprites );\n\t\tvar lensFlarePlugin = new LensFlarePlugin( this, lensFlares );\n\n\t\t// API\n\n\t\tthis.getContext = function () {\n\n\t\t\treturn _gl;\n\n\t\t};\n\n\t\tthis.getContextAttributes = function () {\n\n\t\t\treturn _gl.getContextAttributes();\n\n\t\t};\n\n\t\tthis.forceContextLoss = function () {\n\n\t\t\textensions.get( 'WEBGL_lose_context' ).loseContext();\n\n\t\t};\n\n\t\tthis.getMaxAnisotropy = function () {\n\n\t\t\treturn capabilities.getMaxAnisotropy();\n\n\t\t};\n\n\t\tthis.getPrecision = function () {\n\n\t\t\treturn capabilities.precision;\n\n\t\t};\n\n\t\tthis.getPixelRatio = function () {\n\n\t\t\treturn _pixelRatio;\n\n\t\t};\n\n\t\tthis.setPixelRatio = function ( value ) {\n\n\t\t\tif ( value === undefined ) return;\n\n\t\t\t_pixelRatio = value;\n\n\t\t\tthis.setSize( _viewport.z, _viewport.w, false );\n\n\t\t};\n\n\t\tthis.getSize = function () {\n\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\n\t\t};\n\n\t\tthis.setSize = function ( width, height, updateStyle ) {\n\n\t\t\t_width = width;\n\t\t\t_height = height;\n\n\t\t\t_canvas.width = width * _pixelRatio;\n\t\t\t_canvas.height = height * _pixelRatio;\n\n\t\t\tif ( updateStyle !== false ) {\n\n\t\t\t\t_canvas.style.width = width + 'px';\n\t\t\t\t_canvas.style.height = height + 'px';\n\n\t\t\t}\n\n\t\t\tthis.setViewport( 0, 0, width, height );\n\n\t\t};\n\n\t\tthis.setViewport = function ( x, y, width, height ) {\n\n\t\t\tstate.viewport( _viewport.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissor = function ( x, y, width, height ) {\n\n\t\t\tstate.scissor( _scissor.set( x, y, width, height ) );\n\n\t\t};\n\n\t\tthis.setScissorTest = function ( boolean ) {\n\n\t\t\tstate.setScissorTest( _scissorTest = boolean );\n\n\t\t};\n\n\t\t// Clearing\n\n\t\tthis.getClearColor = function () {\n\n\t\t\treturn _clearColor;\n\n\t\t};\n\n\t\tthis.setClearColor = function ( color, alpha ) {\n\n\t\t\t_clearColor.set( color );\n\n\t\t\t_clearAlpha = alpha !== undefined ? alpha : 1;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.getClearAlpha = function () {\n\n\t\t\treturn _clearAlpha;\n\n\t\t};\n\n\t\tthis.setClearAlpha = function ( alpha ) {\n\n\t\t\t_clearAlpha = alpha;\n\n\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t};\n\n\t\tthis.clear = function ( color, depth, stencil ) {\n\n\t\t\tvar bits = 0;\n\n\t\t\tif ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;\n\t\t\tif ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;\n\t\t\tif ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;\n\n\t\t\t_gl.clear( bits );\n\n\t\t};\n\n\t\tthis.clearColor = function () {\n\n\t\t\tthis.clear( true, false, false );\n\n\t\t};\n\n\t\tthis.clearDepth = function () {\n\n\t\t\tthis.clear( false, true, false );\n\n\t\t};\n\n\t\tthis.clearStencil = function () {\n\n\t\t\tthis.clear( false, false, true );\n\n\t\t};\n\n\t\tthis.clearTarget = function ( renderTarget, color, depth, stencil ) {\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\t\t\tthis.clear( color, depth, stencil );\n\n\t\t};\n\n\t\t// Reset\n\n\t\tthis.resetGLState = resetGLState;\n\n\t\tthis.dispose = function() {\n\n\t\t\ttransparentObjects = [];\n\t\t\ttransparentObjectsLastIndex = -1;\n\t\t\topaqueObjects = [];\n\t\t\topaqueObjectsLastIndex = -1;\n\n\t\t\t_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );\n\n\t\t};\n\n\t\t// Events\n\n\t\tfunction onContextLost( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t\tresetGLState();\n\t\t\tsetDefaultGLState();\n\n\t\t\tproperties.clear();\n\n\t\t}\n\n\t\tfunction onMaterialDispose( event ) {\n\n\t\t\tvar material = event.target;\n\n\t\t\tmaterial.removeEventListener( 'dispose', onMaterialDispose );\n\n\t\t\tdeallocateMaterial( material );\n\n\t\t}\n\n\t\t// Buffer deallocation\n\n\t\tfunction deallocateMaterial( material ) {\n\n\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\tproperties.delete( material );\n\n\t\t}\n\n\n\t\tfunction releaseMaterialProgramReference( material ) {\n\n\t\t\tvar programInfo = properties.get( material ).program;\n\n\t\t\tmaterial.program = undefined;\n\n\t\t\tif ( programInfo !== undefined ) {\n\n\t\t\t\tprogramCache.releaseProgram( programInfo );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Buffer rendering\n\n\t\tthis.renderBufferImmediate = function ( object, program, material ) {\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar buffers = properties.get( object );\n\n\t\t\tif ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();\n\t\t\tif ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();\n\t\t\tif ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();\n\t\t\tif ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( object.hasPositions ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.position );\n\t\t\t\t_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasNormals ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );\n\n\t\t\t\tif ( ! material.isMeshPhongMaterial &&\n\t\t\t\t\t! material.isMeshStandardMaterial &&\n\t\t\t\t\t! material.isMeshNormalMaterial &&\n\t\t\t\t\tmaterial.shading === FlatShading ) {\n\n\t\t\t\t\tfor ( var i = 0, l = object.count * 3; i < l; i += 9 ) {\n\n\t\t\t\t\t\tvar array = object.normalArray;\n\n\t\t\t\t\t\tvar nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;\n\t\t\t\t\t\tvar ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;\n\t\t\t\t\t\tvar nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;\n\n\t\t\t\t\t\tarray[ i + 0 ] = nx;\n\t\t\t\t\t\tarray[ i + 1 ] = ny;\n\t\t\t\t\t\tarray[ i + 2 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 3 ] = nx;\n\t\t\t\t\t\tarray[ i + 4 ] = ny;\n\t\t\t\t\t\tarray[ i + 5 ] = nz;\n\n\t\t\t\t\t\tarray[ i + 6 ] = nx;\n\t\t\t\t\t\tarray[ i + 7 ] = ny;\n\t\t\t\t\t\tarray[ i + 8 ] = nz;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.normal );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasUvs && material.map ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.uv );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( object.hasColors && material.vertexColors !== NoColors ) {\n\n\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );\n\t\t\t\t_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );\n\n\t\t\t\tstate.enableAttribute( attributes.color );\n\n\t\t\t\t_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t\t_gl.drawArrays( _gl.TRIANGLES, 0, object.count );\n\n\t\t\tobject.count = 0;\n\n\t\t};\n\n\t\tthis.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {\n\n\t\t\tsetMaterial( material );\n\n\t\t\tvar program = setProgram( camera, fog, material, object );\n\n\t\t\tvar updateBuffers = false;\n\t\t\tvar geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;\n\n\t\t\tif ( geometryProgram !== _currentGeometryProgram ) {\n\n\t\t\t\t_currentGeometryProgram = geometryProgram;\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t// morph targets\n\n\t\t\tvar morphTargetInfluences = object.morphTargetInfluences;\n\n\t\t\tif ( morphTargetInfluences !== undefined ) {\n\n\t\t\t\tvar activeInfluences = [];\n\n\t\t\t\tfor ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = morphTargetInfluences[ i ];\n\t\t\t\t\tactiveInfluences.push( [ influence, i ] );\n\n\t\t\t\t}\n\n\t\t\t\tactiveInfluences.sort( absNumericalSort );\n\n\t\t\t\tif ( activeInfluences.length > 8 ) {\n\n\t\t\t\t\tactiveInfluences.length = 8;\n\n\t\t\t\t}\n\n\t\t\t\tvar morphAttributes = geometry.morphAttributes;\n\n\t\t\t\tfor ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar influence = activeInfluences[ i ];\n\t\t\t\t\tmorphInfluences[ i ] = influence[ 0 ];\n\n\t\t\t\t\tif ( influence[ 0 ] !== 0 ) {\n\n\t\t\t\t\t\tvar index = influence[ 1 ];\n\n\t\t\t\t\t\tif ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );\n\t\t\t\t\t\tif ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );\n\t\t\t\t\t\tif ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {\n\n\t\t\t\t\tmorphInfluences[ i ] = 0.0;\n\n\t\t\t\t}\n\n\t\t\t\tprogram.getUniforms().setValue(\n\t\t\t\t\t_gl, 'morphTargetInfluences', morphInfluences );\n\n\t\t\t\tupdateBuffers = true;\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar index = geometry.index;\n\t\t\tvar position = geometry.attributes.position;\n\t\t\tvar rangeFactor = 1;\n\n\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\tindex = objects.getWireframeAttribute( geometry );\n\t\t\t\trangeFactor = 2;\n\n\t\t\t}\n\n\t\t\tvar renderer;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\trenderer = indexedBufferRenderer;\n\t\t\t\trenderer.setIndex( index );\n\n\t\t\t} else {\n\n\t\t\t\trenderer = bufferRenderer;\n\n\t\t\t}\n\n\t\t\tif ( updateBuffers ) {\n\n\t\t\t\tsetupVertexAttributes( material, program, geometry );\n\n\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tvar dataCount = 0;\n\n\t\t\tif ( index !== null ) {\n\n\t\t\t\tdataCount = index.count;\n\n\t\t\t} else if ( position !== undefined ) {\n\n\t\t\t\tdataCount = position.count;\n\n\t\t\t}\n\n\t\t\tvar rangeStart = geometry.drawRange.start * rangeFactor;\n\t\t\tvar rangeCount = geometry.drawRange.count * rangeFactor;\n\n\t\t\tvar groupStart = group !== null ? group.start * rangeFactor : 0;\n\t\t\tvar groupCount = group !== null ? group.count * rangeFactor : Infinity;\n\n\t\t\tvar drawStart = Math.max( rangeStart, groupStart );\n\t\t\tvar drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;\n\n\t\t\tvar drawCount = Math.max( 0, drawEnd - drawStart + 1 );\n\n\t\t\tif ( drawCount === 0 ) return;\n\n\t\t\t//\n\n\t\t\tif ( object.isMesh ) {\n\n\t\t\t\tif ( material.wireframe === true ) {\n\n\t\t\t\t\tstate.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tswitch ( object.drawMode ) {\n\n\t\t\t\t\t\tcase TrianglesDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLES );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleStripDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_STRIP );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TriangleFanDrawMode:\n\t\t\t\t\t\t\trenderer.setMode( _gl.TRIANGLE_FAN );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\n\t\t\t} else if ( object.isLine ) {\n\n\t\t\t\tvar lineWidth = material.linewidth;\n\n\t\t\t\tif ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material\n\n\t\t\t\tstate.setLineWidth( lineWidth * getTargetPixelRatio() );\n\n\t\t\t\tif ( object.isLineSegments ) {\n\n\t\t\t\t\trenderer.setMode( _gl.LINES );\n\n\t\t\t\t} else {\n\n\t\t\t\t\trenderer.setMode( _gl.LINE_STRIP );\n\n\t\t\t\t}\n\n\t\t\t} else if ( object.isPoints ) {\n\n\t\t\t\trenderer.setMode( _gl.POINTS );\n\n\t\t\t}\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\tif ( geometry.maxInstancedCount > 0 ) {\n\n\t\t\t\t\trenderer.renderInstances( geometry, drawStart, drawCount );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\trenderer.render( drawStart, drawCount );\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction setupVertexAttributes( material, program, geometry, startIndex ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( geometry && geometry.isInstancedBufferGeometry ) {\n\n\t\t\t\textension = extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t\t\tif ( extension === null ) {\n\n\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( startIndex === undefined ) startIndex = 0;\n\n\t\t\tstate.initAttributes();\n\n\t\t\tvar geometryAttributes = geometry.attributes;\n\n\t\t\tvar programAttributes = program.getAttributes();\n\n\t\t\tvar materialDefaultAttributeValues = material.defaultAttributeValues;\n\n\t\t\tfor ( var name in programAttributes ) {\n\n\t\t\t\tvar programAttribute = programAttributes[ name ];\n\n\t\t\t\tif ( programAttribute >= 0 ) {\n\n\t\t\t\t\tvar geometryAttribute = geometryAttributes[ name ];\n\n\t\t\t\t\tif ( geometryAttribute !== undefined ) {\n\n\t\t\t\t\t\tvar normalized = geometryAttribute.normalized;\n\t\t\t\t\t\tvar size = geometryAttribute.itemSize;\n\n\t\t\t\t\t\tvar attributeProperties = objects.getAttributeProperties( geometryAttribute );\n\n\t\t\t\t\t\tvar buffer = attributeProperties.__webglBuffer;\n\t\t\t\t\t\tvar type = attributeProperties.type;\n\t\t\t\t\t\tvar bytesPerElement = attributeProperties.bytesPerElement;\n\n\t\t\t\t\t\tif ( geometryAttribute.isInterleavedBufferAttribute ) {\n\n\t\t\t\t\t\t\tvar data = geometryAttribute.data;\n\t\t\t\t\t\t\tvar stride = data.stride;\n\t\t\t\t\t\t\tvar offset = geometryAttribute.offset;\n\n\t\t\t\t\t\t\tif ( data && data.isInstancedInterleavedBuffer ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = data.meshPerAttribute * data.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tif ( geometryAttribute.isInstancedBufferAttribute ) {\n\n\t\t\t\t\t\t\t\tstate.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );\n\n\t\t\t\t\t\t\t\tif ( geometry.maxInstancedCount === undefined ) {\n\n\t\t\t\t\t\t\t\t\tgeometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tstate.enableAttribute( programAttribute );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );\n\t\t\t\t\t\t\t_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( materialDefaultAttributeValues !== undefined ) {\n\n\t\t\t\t\t\tvar value = materialDefaultAttributeValues[ name ];\n\n\t\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\t\tswitch ( value.length ) {\n\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib2fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib3fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib4fv( programAttribute, value );\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t_gl.vertexAttrib1fv( programAttribute, value );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.disableUnusedAttributes();\n\n\t\t}\n\n\t\t// Sorting\n\n\t\tfunction absNumericalSort( a, b ) {\n\n\t\t\treturn Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );\n\n\t\t}\n\n\t\tfunction painterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {\n\n\t\t\t\treturn a.material.program.id - b.material.program.id;\n\n\t\t\t} else if ( a.material.id !== b.material.id ) {\n\n\t\t\t\treturn a.material.id - b.material.id;\n\n\t\t\t} else if ( a.z !== b.z ) {\n\n\t\t\t\treturn a.z - b.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction reversePainterSortStable( a, b ) {\n\n\t\t\tif ( a.object.renderOrder !== b.object.renderOrder ) {\n\n\t\t\t\treturn a.object.renderOrder - b.object.renderOrder;\n\n\t\t\t} if ( a.z !== b.z ) {\n\n\t\t\t\treturn b.z - a.z;\n\n\t\t\t} else {\n\n\t\t\t\treturn a.id - b.id;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Rendering\n\n\t\tthis.render = function ( scene, camera, renderTarget, forceClear ) {\n\n\t\t\tif ( camera !== undefined && camera.isCamera !== true ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// reset caching for this frame\n\n\t\t\t_currentGeometryProgram = '';\n\t\t\t_currentMaterialId = - 1;\n\t\t\t_currentCamera = null;\n\n\t\t\t// update scene graph\n\n\t\t\tif ( scene.autoUpdate === true ) scene.updateMatrixWorld();\n\n\t\t\t// update camera matrices and frustum\n\n\t\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\t\t_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );\n\t\t\t_frustum.setFromMatrix( _projScreenMatrix );\n\n\t\t\tlights.length = 0;\n\n\t\t\topaqueObjectsLastIndex = - 1;\n\t\t\ttransparentObjectsLastIndex = - 1;\n\n\t\t\tsprites.length = 0;\n\t\t\tlensFlares.length = 0;\n\n\t\t\t_localClippingEnabled = this.localClippingEnabled;\n\t\t\t_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );\n\n\t\t\tprojectObject( scene, camera );\n\n\t\t\topaqueObjects.length = opaqueObjectsLastIndex + 1;\n\t\t\ttransparentObjects.length = transparentObjectsLastIndex + 1;\n\n\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\topaqueObjects.sort( painterSortStable );\n\t\t\t\ttransparentObjects.sort( reversePainterSortStable );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( _clippingEnabled ) _clipping.beginShadows();\n\n\t\t\tsetupShadows( lights );\n\n\t\t\tshadowMap.render( scene, camera );\n\n\t\t\tsetupLights( lights, camera );\n\n\t\t\tif ( _clippingEnabled ) _clipping.endShadows();\n\n\t\t\t//\n\n\t\t\t_infoRender.calls = 0;\n\t\t\t_infoRender.vertices = 0;\n\t\t\t_infoRender.faces = 0;\n\t\t\t_infoRender.points = 0;\n\n\t\t\tif ( renderTarget === undefined ) {\n\n\t\t\t\trenderTarget = null;\n\n\t\t\t}\n\n\t\t\tthis.setRenderTarget( renderTarget );\n\n\t\t\t//\n\n\t\t\tvar background = scene.background;\n\n\t\t\tif ( background === null ) {\n\n\t\t\t\tstate.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );\n\n\t\t\t} else if ( background && background.isColor ) {\n\n\t\t\t\tstate.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );\n\t\t\t\tforceClear = true;\n\n\t\t\t}\n\n\t\t\tif ( this.autoClear || forceClear ) {\n\n\t\t\t\tthis.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );\n\n\t\t\t}\n\n\t\t\tif ( background && background.isCubeTexture ) {\n\n\t\t\t\tif ( backgroundBoxCamera === undefined ) {\n\n\t\t\t\t\tbackgroundBoxCamera = new PerspectiveCamera();\n\n\t\t\t\t\tbackgroundBoxMesh = new Mesh(\n\t\t\t\t\t\tnew BoxBufferGeometry( 5, 5, 5 ),\n\t\t\t\t\t\tnew ShaderMaterial( {\n\t\t\t\t\t\t\tuniforms: ShaderLib.cube.uniforms,\n\t\t\t\t\t\t\tvertexShader: ShaderLib.cube.vertexShader,\n\t\t\t\t\t\t\tfragmentShader: ShaderLib.cube.fragmentShader,\n\t\t\t\t\t\t\tside: BackSide,\n\t\t\t\t\t\t\tdepthTest: false,\n\t\t\t\t\t\t\tdepthWrite: false,\n\t\t\t\t\t\t\tfog: false\n\t\t\t\t\t\t} )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );\n\n\t\t\t\tbackgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );\n\t\t\t\tbackgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );\n\n\n\t\t\t\tbackgroundBoxMesh.material.uniforms[ \"tCube\" ].value = background;\n\t\t\t\tbackgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );\n\n\t\t\t\tobjects.update( backgroundBoxMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );\n\n\t\t\t} else if ( background && background.isTexture ) {\n\n\t\t\t\tif ( backgroundPlaneCamera === undefined ) {\n\n\t\t\t\t\tbackgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n\t\t\t\t\tbackgroundPlaneMesh = new Mesh(\n\t\t\t\t\t\tnew PlaneBufferGeometry( 2, 2 ),\n\t\t\t\t\t\tnew MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )\n\t\t\t\t\t);\n\n\t\t\t\t}\n\n\t\t\t\tbackgroundPlaneMesh.material.map = background;\n\n\t\t\t\tobjects.update( backgroundPlaneMesh );\n\n\t\t\t\t_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( scene.overrideMaterial ) {\n\n\t\t\t\tvar overrideMaterial = scene.overrideMaterial;\n\n\t\t\t\trenderObjects( opaqueObjects, scene, camera, overrideMaterial );\n\t\t\t\trenderObjects( transparentObjects, scene, camera, overrideMaterial );\n\n\t\t\t} else {\n\n\t\t\t\t// opaque pass (front-to-back order)\n\n\t\t\t\tstate.setBlending( NoBlending );\n\t\t\t\trenderObjects( opaqueObjects, scene, camera );\n\n\t\t\t\t// transparent pass (back-to-front order)\n\n\t\t\t\trenderObjects( transparentObjects, scene, camera );\n\n\t\t\t}\n\n\t\t\t// custom render plugins (post pass)\n\n\t\t\tspritePlugin.render( scene, camera );\n\t\t\tlensFlarePlugin.render( scene, camera, _currentViewport );\n\n\t\t\t// Generate mipmap if we're using any kind of mipmap filtering\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\ttextures.updateRenderTargetMipmap( renderTarget );\n\n\t\t\t}\n\n\t\t\t// Ensure depth buffer writing is enabled so it can be cleared on next render\n\n\t\t\tstate.setDepthTest( true );\n\t\t\tstate.setDepthWrite( true );\n\t\t\tstate.setColorWrite( true );\n\n\t\t\t// _gl.finish();\n\n\t\t};\n\n\t\tfunction pushRenderItem( object, geometry, material, z, group ) {\n\n\t\t\tvar array, index;\n\n\t\t\t// allocate the next position in the appropriate array\n\n\t\t\tif ( material.transparent ) {\n\n\t\t\t\tarray = transparentObjects;\n\t\t\t\tindex = ++ transparentObjectsLastIndex;\n\n\t\t\t} else {\n\n\t\t\t\tarray = opaqueObjects;\n\t\t\t\tindex = ++ opaqueObjectsLastIndex;\n\n\t\t\t}\n\n\t\t\t// recycle existing render item or grow the array\n\n\t\t\tvar renderItem = array[ index ];\n\n\t\t\tif ( renderItem !== undefined ) {\n\n\t\t\t\trenderItem.id = object.id;\n\t\t\t\trenderItem.object = object;\n\t\t\t\trenderItem.geometry = geometry;\n\t\t\t\trenderItem.material = material;\n\t\t\t\trenderItem.z = _vector3.z;\n\t\t\t\trenderItem.group = group;\n\n\t\t\t} else {\n\n\t\t\t\trenderItem = {\n\t\t\t\t\tid: object.id,\n\t\t\t\t\tobject: object,\n\t\t\t\t\tgeometry: geometry,\n\t\t\t\t\tmaterial: material,\n\t\t\t\t\tz: _vector3.z,\n\t\t\t\t\tgroup: group\n\t\t\t\t};\n\n\t\t\t\t// assert( index === array.length );\n\t\t\t\tarray.push( renderItem );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// TODO Duplicated code (Frustum)\n\n\t\tfunction isObjectViewable( object ) {\n\n\t\t\tvar geometry = object.geometry;\n\n\t\t\tif ( geometry.boundingSphere === null )\n\t\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\t_sphere.copy( geometry.boundingSphere ).\n\t\t\tapplyMatrix4( object.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSpriteViewable( sprite ) {\n\n\t\t\t_sphere.center.set( 0, 0, 0 );\n\t\t\t_sphere.radius = 0.7071067811865476;\n\t\t\t_sphere.applyMatrix4( sprite.matrixWorld );\n\n\t\t\treturn isSphereViewable( _sphere );\n\n\t\t}\n\n\t\tfunction isSphereViewable( sphere ) {\n\n\t\t\tif ( ! _frustum.intersectsSphere( sphere ) ) return false;\n\n\t\t\tvar numPlanes = _clipping.numPlanes;\n\n\t\t\tif ( numPlanes === 0 ) return true;\n\n\t\t\tvar planes = _this.clippingPlanes,\n\n\t\t\t\tcenter = sphere.center,\n\t\t\t\tnegRad = - sphere.radius,\n\t\t\t\ti = 0;\n\n\t\t\tdo {\n\n\t\t\t\t// out when deeper than radius in the negative halfspace\n\t\t\t\tif ( planes[ i ].distanceToPoint( center ) < negRad ) return false;\n\n\t\t\t} while ( ++ i !== numPlanes );\n\n\t\t\treturn true;\n\n\t\t}\n\n\t\tfunction projectObject( object, camera ) {\n\n\t\t\tif ( object.visible === false ) return;\n\n\t\t\tvar visible = ( object.layers.mask & camera.layers.mask ) !== 0;\n\n\t\t\tif ( visible ) {\n\n\t\t\t\tif ( object.isLight ) {\n\n\t\t\t\t\tlights.push( object );\n\n\t\t\t\t} else if ( object.isSprite ) {\n\n\t\t\t\t\tif ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {\n\n\t\t\t\t\t\tsprites.push( object );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( object.isLensFlare ) {\n\n\t\t\t\t\tlensFlares.push( object );\n\n\t\t\t\t} else if ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tpushRenderItem( object, null, object.material, _vector3.z, null );\n\n\t\t\t\t} else if ( object.isMesh || object.isLine || object.isPoints ) {\n\n\t\t\t\t\tif ( object.isSkinnedMesh ) {\n\n\t\t\t\t\t\tobject.skeleton.update();\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( object.frustumCulled === false || isObjectViewable( object ) === true ) {\n\n\t\t\t\t\t\tvar material = object.material;\n\n\t\t\t\t\t\tif ( material.visible === true ) {\n\n\t\t\t\t\t\t\tif ( _this.sortObjects === true ) {\n\n\t\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( object.matrixWorld );\n\t\t\t\t\t\t\t\t_vector3.applyMatrix4( _projScreenMatrix );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar geometry = objects.update( object );\n\n\t\t\t\t\t\t\tif ( material.isMultiMaterial ) {\n\n\t\t\t\t\t\t\t\tvar groups = geometry.groups;\n\t\t\t\t\t\t\t\tvar materials = material.materials;\n\n\t\t\t\t\t\t\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\t\t\t\t\t\t\tvar group = groups[ i ];\n\t\t\t\t\t\t\t\t\tvar groupMaterial = materials[ group.materialIndex ];\n\n\t\t\t\t\t\t\t\t\tif ( groupMaterial.visible === true ) {\n\n\t\t\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, groupMaterial, _vector3.z, group );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tpushRenderItem( object, geometry, material, _vector3.z, null );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tprojectObject( children[ i ], camera );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction renderObjects( renderList, scene, camera, overrideMaterial ) {\n\n\t\t\tfor ( var i = 0, l = renderList.length; i < l; i ++ ) {\n\n\t\t\t\tvar renderItem = renderList[ i ];\n\n\t\t\t\tvar object = renderItem.object;\n\t\t\t\tvar geometry = renderItem.geometry;\n\t\t\t\tvar material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;\n\t\t\t\tvar group = renderItem.group;\n\n\t\t\t\tobject.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );\n\t\t\t\tobject.normalMatrix.getNormalMatrix( object.modelViewMatrix );\n\n\t\t\t\tobject.onBeforeRender( _this, scene, camera, geometry, material, group );\n\n\t\t\t\tif ( object.isImmediateRenderObject ) {\n\n\t\t\t\t\tsetMaterial( material );\n\n\t\t\t\t\tvar program = setProgram( camera, scene.fog, material, object );\n\n\t\t\t\t\t_currentGeometryProgram = '';\n\n\t\t\t\t\tobject.render( function ( object ) {\n\n\t\t\t\t\t\t_this.renderBufferImmediate( object, program, material );\n\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );\n\n\t\t\t\t}\n\n\t\t\t\tobject.onAfterRender( _this, scene, camera, geometry, material, group );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initMaterial( material, fog, object ) {\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tvar parameters = programCache.getParameters(\n\t\t\t\tmaterial, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );\n\n\t\t\tvar code = programCache.getProgramCode( material, parameters );\n\n\t\t\tvar program = materialProperties.program;\n\t\t\tvar programChange = true;\n\n\t\t\tif ( program === undefined ) {\n\n\t\t\t\t// new material\n\t\t\t\tmaterial.addEventListener( 'dispose', onMaterialDispose );\n\n\t\t\t} else if ( program.code !== code ) {\n\n\t\t\t\t// changed glsl or parameters\n\t\t\t\treleaseMaterialProgramReference( material );\n\n\t\t\t} else if ( parameters.shaderID !== undefined ) {\n\n\t\t\t\t// same glsl and uniform list\n\t\t\t\treturn;\n\n\t\t\t} else {\n\n\t\t\t\t// only rebuild uniform list\n\t\t\t\tprogramChange = false;\n\n\t\t\t}\n\n\t\t\tif ( programChange ) {\n\n\t\t\t\tif ( parameters.shaderID ) {\n\n\t\t\t\t\tvar shader = ShaderLib[ parameters.shaderID ];\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: UniformsUtils.clone( shader.uniforms ),\n\t\t\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\t\t\tfragmentShader: shader.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t} else {\n\n\t\t\t\t\tmaterialProperties.__webglShader = {\n\t\t\t\t\t\tname: material.type,\n\t\t\t\t\t\tuniforms: material.uniforms,\n\t\t\t\t\t\tvertexShader: material.vertexShader,\n\t\t\t\t\t\tfragmentShader: material.fragmentShader\n\t\t\t\t\t};\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.__webglShader = materialProperties.__webglShader;\n\n\t\t\t\tprogram = programCache.acquireProgram( material, parameters, code );\n\n\t\t\t\tmaterialProperties.program = program;\n\t\t\t\tmaterial.program = program;\n\n\t\t\t}\n\n\t\t\tvar attributes = program.getAttributes();\n\n\t\t\tif ( material.morphTargets ) {\n\n\t\t\t\tmaterial.numSupportedMorphTargets = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphTargets; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphTarget' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphTargets ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.morphNormals ) {\n\n\t\t\t\tmaterial.numSupportedMorphNormals = 0;\n\n\t\t\t\tfor ( var i = 0; i < _this.maxMorphNormals; i ++ ) {\n\n\t\t\t\t\tif ( attributes[ 'morphNormal' + i ] >= 0 ) {\n\n\t\t\t\t\t\tmaterial.numSupportedMorphNormals ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( ! material.isShaderMaterial &&\n\t\t\t\t! material.isRawShaderMaterial ||\n\t\t\t\tmaterial.clipping === true ) {\n\n\t\t\t\tmaterialProperties.numClippingPlanes = _clipping.numPlanes;\n\t\t\t\tmaterialProperties.numIntersection = _clipping.numIntersection;\n\t\t\t\tuniforms.clippingPlanes = _clipping.uniform;\n\n\t\t\t}\n\n\t\t\tmaterialProperties.fog = fog;\n\n\t\t\t// store the light setup it was created for\n\n\t\t\tmaterialProperties.lightsHash = _lights.hash;\n\n\t\t\tif ( material.lights ) {\n\n\t\t\t\t// wire up the material to this renderer's lighting state\n\n\t\t\t\tuniforms.ambientLightColor.value = _lights.ambient;\n\t\t\t\tuniforms.directionalLights.value = _lights.directional;\n\t\t\t\tuniforms.spotLights.value = _lights.spot;\n\t\t\t\tuniforms.rectAreaLights.value = _lights.rectArea;\n\t\t\t\tuniforms.pointLights.value = _lights.point;\n\t\t\t\tuniforms.hemisphereLights.value = _lights.hemi;\n\n\t\t\t\tuniforms.directionalShadowMap.value = _lights.directionalShadowMap;\n\t\t\t\tuniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;\n\t\t\t\tuniforms.spotShadowMap.value = _lights.spotShadowMap;\n\t\t\t\tuniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;\n\t\t\t\tuniforms.pointShadowMap.value = _lights.pointShadowMap;\n\t\t\t\tuniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;\n\t\t\t\t// TODO (abelnation): add area lights shadow info to uniforms\n\n\t\t\t}\n\n\t\t\tvar progUniforms = materialProperties.program.getUniforms(),\n\t\t\t\tuniformsList =\n\t\t\t\t\tWebGLUniforms.seqWithValue( progUniforms.seq, uniforms );\n\n\t\t\tmaterialProperties.uniformsList = uniformsList;\n\n\t\t}\n\n\t\tfunction setMaterial( material ) {\n\n\t\t\tmaterial.side === DoubleSide\n\t\t\t\t? state.disable( _gl.CULL_FACE )\n\t\t\t\t: state.enable( _gl.CULL_FACE );\n\n\t\t\tstate.setFlipSided( material.side === BackSide );\n\n\t\t\tmaterial.transparent === true\n\t\t\t\t? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )\n\t\t\t\t: state.setBlending( NoBlending );\n\n\t\t\tstate.setDepthFunc( material.depthFunc );\n\t\t\tstate.setDepthTest( material.depthTest );\n\t\t\tstate.setDepthWrite( material.depthWrite );\n\t\t\tstate.setColorWrite( material.colorWrite );\n\t\t\tstate.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );\n\n\t\t}\n\n\t\tfunction setProgram( camera, fog, material, object ) {\n\n\t\t\t_usedTextureUnits = 0;\n\n\t\t\tvar materialProperties = properties.get( material );\n\n\t\t\tif ( _clippingEnabled ) {\n\n\t\t\t\tif ( _localClippingEnabled || camera !== _currentCamera ) {\n\n\t\t\t\t\tvar useCache =\n\t\t\t\t\t\tcamera === _currentCamera &&\n\t\t\t\t\t\tmaterial.id === _currentMaterialId;\n\n\t\t\t\t\t// we might want to call this function with some ClippingGroup\n\t\t\t\t\t// object instead of the material, once it becomes feasible\n\t\t\t\t\t// (#8465, #8379)\n\t\t\t\t\t_clipping.setState(\n\t\t\t\t\t\tmaterial.clippingPlanes, material.clipIntersection, material.clipShadows,\n\t\t\t\t\t\tcamera, materialProperties, useCache );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate === false ) {\n\n\t\t\t\tif ( materialProperties.program === undefined ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.fog && materialProperties.fog !== fog ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t} else if ( materialProperties.numClippingPlanes !== undefined &&\n\t\t\t\t\t( materialProperties.numClippingPlanes !== _clipping.numPlanes ||\n\t\t\t\t\tmaterialProperties.numIntersection !== _clipping.numIntersection ) ) {\n\n\t\t\t\t\tmaterial.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( material.needsUpdate ) {\n\n\t\t\t\tinitMaterial( material, fog, object );\n\t\t\t\tmaterial.needsUpdate = false;\n\n\t\t\t}\n\n\t\t\tvar refreshProgram = false;\n\t\t\tvar refreshMaterial = false;\n\t\t\tvar refreshLights = false;\n\n\t\t\tvar program = materialProperties.program,\n\t\t\t\tp_uniforms = program.getUniforms(),\n\t\t\t\tm_uniforms = materialProperties.__webglShader.uniforms;\n\n\t\t\tif ( program.id !== _currentProgram ) {\n\n\t\t\t\t_gl.useProgram( program.program );\n\t\t\t\t_currentProgram = program.id;\n\n\t\t\t\trefreshProgram = true;\n\t\t\t\trefreshMaterial = true;\n\t\t\t\trefreshLights = true;\n\n\t\t\t}\n\n\t\t\tif ( material.id !== _currentMaterialId ) {\n\n\t\t\t\t_currentMaterialId = material.id;\n\n\t\t\t\trefreshMaterial = true;\n\n\t\t\t}\n\n\t\t\tif ( refreshProgram || camera !== _currentCamera ) {\n\n\t\t\t\tp_uniforms.set( _gl, camera, 'projectionMatrix' );\n\n\t\t\t\tif ( capabilities.logarithmicDepthBuffer ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'logDepthBufFC',\n\t\t\t\t\t\t2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( camera !== _currentCamera ) {\n\n\t\t\t\t\t_currentCamera = camera;\n\n\t\t\t\t\t// lighting uniforms depend on the camera so enforce an update\n\t\t\t\t\t// now, in case this material supports lights - or later, when\n\t\t\t\t\t// the next material that does gets activated:\n\n\t\t\t\t\trefreshMaterial = true;\t\t// set to true on material change\n\t\t\t\t\trefreshLights = true;\t\t// remains set until update done\n\n\t\t\t\t}\n\n\t\t\t\t// load material specific uniforms\n\t\t\t\t// (shader material also gets them for the sake of genericity)\n\n\t\t\t\tif ( material.isShaderMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.envMap ) {\n\n\t\t\t\t\tvar uCamPos = p_uniforms.map.cameraPosition;\n\n\t\t\t\t\tif ( uCamPos !== undefined ) {\n\n\t\t\t\t\t\tuCamPos.setValue( _gl,\n\t\t\t\t\t\t\t_vector3.setFromMatrixPosition( camera.matrixWorld ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isShaderMaterial ||\n\t\t\t\t\tmaterial.skinning ) {\n\n\t\t\t\t\tp_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );\n\n\t\t\t\t}\n\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingExposure' );\n\t\t\t\tp_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );\n\n\t\t\t}\n\n\t\t\t// skinning uniforms must be set even if material didn't change\n\t\t\t// auto-setting of texture unit for bone texture must go before other textures\n\t\t\t// not sure why, but otherwise weird things happen\n\n\t\t\tif ( material.skinning ) {\n\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrix' );\n\t\t\t\tp_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );\n\n\t\t\t\tvar skeleton = object.skeleton;\n\n\t\t\t\tif ( skeleton ) {\n\n\t\t\t\t\tif ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {\n\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTexture' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureWidth' );\n\t\t\t\t\t\tp_uniforms.set( _gl, skeleton, 'boneTextureHeight' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tp_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( refreshMaterial ) {\n\n\t\t\t\tif ( material.lights ) {\n\n\t\t\t\t\t// the current material requires lighting info\n\n\t\t\t\t\t// note: all lighting uniforms are always set correctly\n\t\t\t\t\t// they simply reference the renderer's state for their\n\t\t\t\t\t// values\n\t\t\t\t\t//\n\t\t\t\t\t// use the current material's .needsUpdate flags to set\n\t\t\t\t\t// the GL state when required\n\n\t\t\t\t\tmarkUniformsLightsNeedsUpdate( m_uniforms, refreshLights );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh uniforms common to several materials\n\n\t\t\t\tif ( fog && material.fog ) {\n\n\t\t\t\t\trefreshUniformsFog( m_uniforms, fog );\n\n\t\t\t\t}\n\n\t\t\t\tif ( material.isMeshBasicMaterial ||\n\t\t\t\t\tmaterial.isMeshLambertMaterial ||\n\t\t\t\t\tmaterial.isMeshPhongMaterial ||\n\t\t\t\t\tmaterial.isMeshStandardMaterial ||\n\t\t\t\t\tmaterial.isMeshNormalMaterial ||\n\t\t\t\t\tmaterial.isMeshDepthMaterial ) {\n\n\t\t\t\t\trefreshUniformsCommon( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// refresh single material specific uniforms\n\n\t\t\t\tif ( material.isLineBasicMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isLineDashedMaterial ) {\n\n\t\t\t\t\trefreshUniformsLine( m_uniforms, material );\n\t\t\t\t\trefreshUniformsDash( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isPointsMaterial ) {\n\n\t\t\t\t\trefreshUniformsPoints( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshLambertMaterial ) {\n\n\t\t\t\t\trefreshUniformsLambert( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshToonMaterial ) {\n\n\t\t\t\t\trefreshUniformsToon( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhongMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhong( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshPhysicalMaterial ) {\n\n\t\t\t\t\trefreshUniformsPhysical( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshStandardMaterial ) {\n\n\t\t\t\t\trefreshUniformsStandard( m_uniforms, material );\n\n\t\t\t\t} else if ( material.isMeshDepthMaterial ) {\n\n\t\t\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\t\t\tm_uniforms.displacementMap.value = material.displacementMap;\n\t\t\t\t\t\tm_uniforms.displacementScale.value = material.displacementScale;\n\t\t\t\t\t\tm_uniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( material.isMeshNormalMaterial ) {\n\n\t\t\t\t\trefreshUniformsNormal( m_uniforms, material );\n\n\t\t\t\t}\n\n\t\t\t\t// RectAreaLight Texture\n\t\t\t\t// TODO (mrdoob): Find a nicer implementation\n\n\t\t\t\tif ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;\n\t\t\t\tif ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;\n\n\t\t\t\tWebGLUniforms.upload(\n\t\t\t\t\t_gl, materialProperties.uniformsList, m_uniforms, _this );\n\n\t\t\t}\n\n\n\t\t\t// common matrices\n\n\t\t\tp_uniforms.set( _gl, object, 'modelViewMatrix' );\n\t\t\tp_uniforms.set( _gl, object, 'normalMatrix' );\n\t\t\tp_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );\n\n\t\t\treturn program;\n\n\t\t}\n\n\t\t// Uniforms (refresh uniforms objects)\n\n\t\tfunction refreshUniformsCommon( uniforms, material ) {\n\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t\tuniforms.diffuse.value = material.color;\n\n\t\t\tif ( material.emissive ) {\n\n\t\t\t\tuniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );\n\n\t\t\t}\n\n\t\t\tuniforms.map.value = material.map;\n\t\t\tuniforms.specularMap.value = material.specularMap;\n\t\t\tuniforms.alphaMap.value = material.alphaMap;\n\n\t\t\tif ( material.lightMap ) {\n\n\t\t\t\tuniforms.lightMap.value = material.lightMap;\n\t\t\t\tuniforms.lightMapIntensity.value = material.lightMapIntensity;\n\n\t\t\t}\n\n\t\t\tif ( material.aoMap ) {\n\n\t\t\t\tuniforms.aoMap.value = material.aoMap;\n\t\t\t\tuniforms.aoMapIntensity.value = material.aoMapIntensity;\n\n\t\t\t}\n\n\t\t\t// uv repeat and offset setting priorities\n\t\t\t// 1. color map\n\t\t\t// 2. specular map\n\t\t\t// 3. normal map\n\t\t\t// 4. bump map\n\t\t\t// 5. alpha map\n\t\t\t// 6. emissive map\n\n\t\t\tvar uvScaleMap;\n\n\t\t\tif ( material.map ) {\n\n\t\t\t\tuvScaleMap = material.map;\n\n\t\t\t} else if ( material.specularMap ) {\n\n\t\t\t\tuvScaleMap = material.specularMap;\n\n\t\t\t} else if ( material.displacementMap ) {\n\n\t\t\t\tuvScaleMap = material.displacementMap;\n\n\t\t\t} else if ( material.normalMap ) {\n\n\t\t\t\tuvScaleMap = material.normalMap;\n\n\t\t\t} else if ( material.bumpMap ) {\n\n\t\t\t\tuvScaleMap = material.bumpMap;\n\n\t\t\t} else if ( material.roughnessMap ) {\n\n\t\t\t\tuvScaleMap = material.roughnessMap;\n\n\t\t\t} else if ( material.metalnessMap ) {\n\n\t\t\t\tuvScaleMap = material.metalnessMap;\n\n\t\t\t} else if ( material.alphaMap ) {\n\n\t\t\t\tuvScaleMap = material.alphaMap;\n\n\t\t\t} else if ( material.emissiveMap ) {\n\n\t\t\t\tuvScaleMap = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( uvScaleMap !== undefined ) {\n\n\t\t\t\t// backwards compatibility\n\t\t\t\tif ( uvScaleMap.isWebGLRenderTarget ) {\n\n\t\t\t\t\tuvScaleMap = uvScaleMap.texture;\n\n\t\t\t\t}\n\n\t\t\t\tvar offset = uvScaleMap.offset;\n\t\t\t\tvar repeat = uvScaleMap.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t\tuniforms.envMap.value = material.envMap;\n\n\t\t\t// don't flip CubeTexture envMaps, flip everything else:\n\t\t\t// WebGLRenderTargetCube will be flipped for backwards compatibility\n\t\t\t// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture\n\t\t\t// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future\n\t\t\tuniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;\n\n\t\t\tuniforms.reflectivity.value = material.reflectivity;\n\t\t\tuniforms.refractionRatio.value = material.refractionRatio;\n\n\t\t}\n\n\t\tfunction refreshUniformsLine( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\n\t\t}\n\n\t\tfunction refreshUniformsDash( uniforms, material ) {\n\n\t\t\tuniforms.dashSize.value = material.dashSize;\n\t\t\tuniforms.totalSize.value = material.dashSize + material.gapSize;\n\t\t\tuniforms.scale.value = material.scale;\n\n\t\t}\n\n\t\tfunction refreshUniformsPoints( uniforms, material ) {\n\n\t\t\tuniforms.diffuse.value = material.color;\n\t\t\tuniforms.opacity.value = material.opacity;\n\t\t\tuniforms.size.value = material.size * _pixelRatio;\n\t\t\tuniforms.scale.value = _height * 0.5;\n\n\t\t\tuniforms.map.value = material.map;\n\n\t\t\tif ( material.map !== null ) {\n\n\t\t\t\tvar offset = material.map.offset;\n\t\t\t\tvar repeat = material.map.repeat;\n\n\t\t\t\tuniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsFog( uniforms, fog ) {\n\n\t\t\tuniforms.fogColor.value = fog.color;\n\n\t\t\tif ( fog.isFog ) {\n\n\t\t\t\tuniforms.fogNear.value = fog.near;\n\t\t\t\tuniforms.fogFar.value = fog.far;\n\n\t\t\t} else if ( fog.isFogExp2 ) {\n\n\t\t\t\tuniforms.fogDensity.value = fog.density;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsLambert( uniforms, material ) {\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhong( uniforms, material ) {\n\n\t\t\tuniforms.specular.value = material.specular;\n\t\t\tuniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsToon( uniforms, material ) {\n\n\t\t\trefreshUniformsPhong( uniforms, material );\n\n\t\t\tif ( material.gradientMap ) {\n\n\t\t\t\tuniforms.gradientMap.value = material.gradientMap;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsStandard( uniforms, material ) {\n\n\t\t\tuniforms.roughness.value = material.roughness;\n\t\t\tuniforms.metalness.value = material.metalness;\n\n\t\t\tif ( material.roughnessMap ) {\n\n\t\t\t\tuniforms.roughnessMap.value = material.roughnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.metalnessMap ) {\n\n\t\t\t\tuniforms.metalnessMap.value = material.metalnessMap;\n\n\t\t\t}\n\n\t\t\tif ( material.emissiveMap ) {\n\n\t\t\t\tuniforms.emissiveMap.value = material.emissiveMap;\n\n\t\t\t}\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t\tif ( material.envMap ) {\n\n\t\t\t\t//uniforms.envMap.value = material.envMap; // part of uniforms common\n\t\t\t\tuniforms.envMapIntensity.value = material.envMapIntensity;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction refreshUniformsPhysical( uniforms, material ) {\n\n\t\t\tuniforms.clearCoat.value = material.clearCoat;\n\t\t\tuniforms.clearCoatRoughness.value = material.clearCoatRoughness;\n\n\t\t\trefreshUniformsStandard( uniforms, material );\n\n\t\t}\n\n\t\tfunction refreshUniformsNormal( uniforms, material ) {\n\n\t\t\tif ( material.bumpMap ) {\n\n\t\t\t\tuniforms.bumpMap.value = material.bumpMap;\n\t\t\t\tuniforms.bumpScale.value = material.bumpScale;\n\n\t\t\t}\n\n\t\t\tif ( material.normalMap ) {\n\n\t\t\t\tuniforms.normalMap.value = material.normalMap;\n\t\t\t\tuniforms.normalScale.value.copy( material.normalScale );\n\n\t\t\t}\n\n\t\t\tif ( material.displacementMap ) {\n\n\t\t\t\tuniforms.displacementMap.value = material.displacementMap;\n\t\t\t\tuniforms.displacementScale.value = material.displacementScale;\n\t\t\t\tuniforms.displacementBias.value = material.displacementBias;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// If uniforms are marked as clean, they don't need to be loaded to the GPU.\n\n\t\tfunction markUniformsLightsNeedsUpdate( uniforms, value ) {\n\n\t\t\tuniforms.ambientLightColor.needsUpdate = value;\n\n\t\t\tuniforms.directionalLights.needsUpdate = value;\n\t\t\tuniforms.pointLights.needsUpdate = value;\n\t\t\tuniforms.spotLights.needsUpdate = value;\n\t\t\tuniforms.rectAreaLights.needsUpdate = value;\n\t\t\tuniforms.hemisphereLights.needsUpdate = value;\n\n\t\t}\n\n\t\t// Lighting\n\n\t\tfunction setupShadows( lights ) {\n\n\t\t\tvar lightShadowsLength = 0;\n\n\t\t\tfor ( var i = 0, l = lights.length; i < l; i ++ ) {\n\n\t\t\t\tvar light = lights[ i ];\n\n\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t_lights.shadows[ lightShadowsLength ++ ] = light;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.shadows.length = lightShadowsLength;\n\n\t\t}\n\n\t\tfunction setupLights( lights, camera ) {\n\n\t\t\tvar l, ll, light,\n\t\t\t\tr = 0, g = 0, b = 0,\n\t\t\t\tcolor,\n\t\t\t\tintensity,\n\t\t\t\tdistance,\n\t\t\t\tshadowMap,\n\n\t\t\t\tviewMatrix = camera.matrixWorldInverse,\n\n\t\t\tdirectionalLength = 0,\n\t\t\tpointLength = 0,\n\t\t\tspotLength = 0,\n\t\t\trectAreaLength = 0,\n\t\t\themiLength = 0;\n\n\t\t\tfor ( l = 0, ll = lights.length; l < ll; l ++ ) {\n\n\t\t\t\tlight = lights[ l ];\n\n\t\t\t\tcolor = light.color;\n\t\t\t\tintensity = light.intensity;\n\t\t\t\tdistance = light.distance;\n\n\t\t\t\tshadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;\n\n\t\t\t\tif ( light.isAmbientLight ) {\n\n\t\t\t\t\tr += color.r * intensity;\n\t\t\t\t\tg += color.g * intensity;\n\t\t\t\t\tb += color.b * intensity;\n\n\t\t\t\t} else if ( light.isDirectionalLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.directionalShadowMap[ directionalLength ] = shadowMap;\n\t\t\t\t\t_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.directional[ directionalLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isSpotLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.distance = distance;\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.target.matrixWorld );\n\t\t\t\t\tuniforms.direction.sub( _vector3 );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\n\t\t\t\t\tuniforms.coneCos = Math.cos( light.angle );\n\t\t\t\t\tuniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.spotShadowMap[ spotLength ] = shadowMap;\n\t\t\t\t\t_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;\n\t\t\t\t\t_lights.spot[ spotLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isRectAreaLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\t// (a) intensity controls irradiance of entire light\n\t\t\t\t\tuniforms.color\n\t\t\t\t\t\t.copy( color )\n\t\t\t\t\t\t.multiplyScalar( intensity / ( light.width * light.height ) );\n\n\t\t\t\t\t// (b) intensity controls the radiance per light area\n\t\t\t\t\t// uniforms.color.copy( color ).multiplyScalar( intensity );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\t// extract local rotation of light to derive width/height half vectors\n\t\t\t\t\t_matrix42.identity();\n\t\t\t\t\t_matrix4.copy( light.matrixWorld );\n\t\t\t\t\t_matrix4.premultiply( viewMatrix );\n\t\t\t\t\t_matrix42.extractRotation( _matrix4 );\n\n\t\t\t\t\tuniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );\n\t\t\t\t\tuniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );\n\n\t\t\t\t\tuniforms.halfWidth.applyMatrix4( _matrix42 );\n\t\t\t\t\tuniforms.halfHeight.applyMatrix4( _matrix42 );\n\n\t\t\t\t\t// TODO (abelnation): RectAreaLight distance?\n\t\t\t\t\t// uniforms.distance = distance;\n\n\t\t\t\t\t_lights.rectArea[ rectAreaLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isPointLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.position.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.position.applyMatrix4( viewMatrix );\n\n\t\t\t\t\tuniforms.color.copy( light.color ).multiplyScalar( light.intensity );\n\t\t\t\t\tuniforms.distance = light.distance;\n\t\t\t\t\tuniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;\n\n\t\t\t\t\tuniforms.shadow = light.castShadow;\n\n\t\t\t\t\tif ( light.castShadow ) {\n\n\t\t\t\t\t\tuniforms.shadowBias = light.shadow.bias;\n\t\t\t\t\t\tuniforms.shadowRadius = light.shadow.radius;\n\t\t\t\t\t\tuniforms.shadowMapSize = light.shadow.mapSize;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_lights.pointShadowMap[ pointLength ] = shadowMap;\n\n\t\t\t\t\tif ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {\n\n\t\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ] = new Matrix4();\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// for point lights we set the shadow matrix to be a translation-only matrix\n\t\t\t\t\t// equal to inverse of the light's position\n\t\t\t\t\t_vector3.setFromMatrixPosition( light.matrixWorld ).negate();\n\t\t\t\t\t_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );\n\n\t\t\t\t\t_lights.point[ pointLength ++ ] = uniforms;\n\n\t\t\t\t} else if ( light.isHemisphereLight ) {\n\n\t\t\t\t\tvar uniforms = lightCache.get( light );\n\n\t\t\t\t\tuniforms.direction.setFromMatrixPosition( light.matrixWorld );\n\t\t\t\t\tuniforms.direction.transformDirection( viewMatrix );\n\t\t\t\t\tuniforms.direction.normalize();\n\n\t\t\t\t\tuniforms.skyColor.copy( light.color ).multiplyScalar( intensity );\n\t\t\t\t\tuniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );\n\n\t\t\t\t\t_lights.hemi[ hemiLength ++ ] = uniforms;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t_lights.ambient[ 0 ] = r;\n\t\t\t_lights.ambient[ 1 ] = g;\n\t\t\t_lights.ambient[ 2 ] = b;\n\n\t\t\t_lights.directional.length = directionalLength;\n\t\t\t_lights.spot.length = spotLength;\n\t\t\t_lights.rectArea.length = rectAreaLength;\n\t\t\t_lights.point.length = pointLength;\n\t\t\t_lights.hemi.length = hemiLength;\n\n\t\t\t// TODO (sam-g-steel) why aren't we using join\n\t\t\t_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;\n\n\t\t}\n\n\t\t// GL state setting\n\n\t\tthis.setFaceCulling = function ( cullFace, frontFaceDirection ) {\n\n\t\t\tstate.setCullFace( cullFace );\n\t\t\tstate.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );\n\n\t\t};\n\n\t\t// Textures\n\n\t\tfunction allocTextureUnit() {\n\n\t\t\tvar textureUnit = _usedTextureUnits;\n\n\t\t\tif ( textureUnit >= capabilities.maxTextures ) {\n\n\t\t\t\tconsole.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );\n\n\t\t\t}\n\n\t\t\t_usedTextureUnits += 1;\n\n\t\t\treturn textureUnit;\n\n\t\t}\n\n\t\tthis.allocTextureUnit = allocTextureUnit;\n\n\t\t// this.setTexture2D = setTexture2D;\n\t\tthis.setTexture2D = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\t// backwards compatibility: peel texture.texture\n\t\t\treturn function setTexture2D( texture, slot ) {\n\n\t\t\t\tif ( texture && texture.isWebGLRenderTarget ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTexture = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTexture( texture, slot ) {\n\n\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead.\" );\n\t\t\t\t\twarned = true;\n\n\t\t\t\t}\n\n\t\t\t\ttextures.setTexture2D( texture, slot );\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.setTextureCube = ( function() {\n\n\t\t\tvar warned = false;\n\n\t\t\treturn function setTextureCube( texture, slot ) {\n\n\t\t\t\t// backwards compatibility: peel texture.texture\n\t\t\t\tif ( texture && texture.isWebGLRenderTargetCube ) {\n\n\t\t\t\t\tif ( ! warned ) {\n\n\t\t\t\t\t\tconsole.warn( \"THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead.\" );\n\t\t\t\t\t\twarned = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture = texture.texture;\n\n\t\t\t\t}\n\n\t\t\t\t// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture\n\t\t\t\t// TODO: unify these code paths\n\t\t\t\tif ( ( texture && texture.isCubeTexture ) ||\n\t\t\t\t\t( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {\n\n\t\t\t\t\t// CompressedTexture can have Array in image :/\n\n\t\t\t\t\t// this function alone should take care of cube textures\n\t\t\t\t\ttextures.setTextureCube( texture, slot );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// assumed: texture property of THREE.WebGLRenderTargetCube\n\n\t\t\t\t\ttextures.setTextureCubeDynamic( texture, slot );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() );\n\n\t\tthis.getCurrentRenderTarget = function() {\n\n\t\t\treturn _currentRenderTarget;\n\n\t\t};\n\n\t\tthis.setRenderTarget = function ( renderTarget ) {\n\n\t\t\t_currentRenderTarget = renderTarget;\n\n\t\t\tif ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {\n\n\t\t\t\ttextures.setupRenderTarget( renderTarget );\n\n\t\t\t}\n\n\t\t\tvar isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );\n\t\t\tvar framebuffer;\n\n\t\t\tif ( renderTarget ) {\n\n\t\t\t\tvar renderTargetProperties = properties.get( renderTarget );\n\n\t\t\t\tif ( isCube ) {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\tframebuffer = renderTargetProperties.__webglFramebuffer;\n\n\t\t\t\t}\n\n\t\t\t\t_currentScissor.copy( renderTarget.scissor );\n\t\t\t\t_currentScissorTest = renderTarget.scissorTest;\n\n\t\t\t\t_currentViewport.copy( renderTarget.viewport );\n\n\t\t\t} else {\n\n\t\t\t\tframebuffer = null;\n\n\t\t\t\t_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );\n\t\t\t\t_currentScissorTest = _scissorTest;\n\n\t\t\t\t_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );\n\n\t\t\t}\n\n\t\t\tif ( _currentFramebuffer !== framebuffer ) {\n\n\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\t\t\t\t_currentFramebuffer = framebuffer;\n\n\t\t\t}\n\n\t\t\tstate.scissor( _currentScissor );\n\t\t\tstate.setScissorTest( _currentScissorTest );\n\n\t\t\tstate.viewport( _currentViewport );\n\n\t\t\tif ( isCube ) {\n\n\t\t\t\tvar textureProperties = properties.get( renderTarget.texture );\n\t\t\t\t_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {\n\n\t\t\tif ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {\n\n\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar framebuffer = properties.get( renderTarget ).__webglFramebuffer;\n\n\t\t\tif ( framebuffer ) {\n\n\t\t\t\tvar restore = false;\n\n\t\t\t\tif ( framebuffer !== _currentFramebuffer ) {\n\n\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\t\t\t\t\trestore = true;\n\n\t\t\t\t}\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar texture = renderTarget.texture;\n\t\t\t\t\tvar textureFormat = texture.format;\n\t\t\t\t\tvar textureType = texture.type;\n\n\t\t\t\t\tif ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)\n\t\t\t\t\t\t! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox\n\t\t\t\t\t\t! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {\n\n\t\t\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\n\t\t\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t\t\t_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} finally {\n\n\t\t\t\t\tif ( restore ) {\n\n\t\t\t\t\t\t_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Map three.js constants to WebGL constants\n\n\t\tfunction paramThreeToGL( p ) {\n\n\t\t\tvar extension;\n\n\t\t\tif ( p === RepeatWrapping ) return _gl.REPEAT;\n\t\t\tif ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;\n\t\t\tif ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;\n\n\t\t\tif ( p === NearestFilter ) return _gl.NEAREST;\n\t\t\tif ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;\n\t\t\tif ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;\n\n\t\t\tif ( p === LinearFilter ) return _gl.LINEAR;\n\t\t\tif ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;\n\t\t\tif ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;\n\n\t\t\tif ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;\n\t\t\tif ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;\n\t\t\tif ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;\n\t\t\tif ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;\n\n\t\t\tif ( p === ByteType ) return _gl.BYTE;\n\t\t\tif ( p === ShortType ) return _gl.SHORT;\n\t\t\tif ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;\n\t\t\tif ( p === IntType ) return _gl.INT;\n\t\t\tif ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;\n\t\t\tif ( p === FloatType ) return _gl.FLOAT;\n\n\t\t\tif ( p === HalfFloatType ) {\n\n\t\t\t\textension = extensions.get( 'OES_texture_half_float' );\n\n\t\t\t\tif ( extension !== null ) return extension.HALF_FLOAT_OES;\n\n\t\t\t}\n\n\t\t\tif ( p === AlphaFormat ) return _gl.ALPHA;\n\t\t\tif ( p === RGBFormat ) return _gl.RGB;\n\t\t\tif ( p === RGBAFormat ) return _gl.RGBA;\n\t\t\tif ( p === LuminanceFormat ) return _gl.LUMINANCE;\n\t\t\tif ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;\n\t\t\tif ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;\n\t\t\tif ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;\n\n\t\t\tif ( p === AddEquation ) return _gl.FUNC_ADD;\n\t\t\tif ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;\n\t\t\tif ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;\n\n\t\t\tif ( p === ZeroFactor ) return _gl.ZERO;\n\t\t\tif ( p === OneFactor ) return _gl.ONE;\n\t\t\tif ( p === SrcColorFactor ) return _gl.SRC_COLOR;\n\t\t\tif ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;\n\t\t\tif ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;\n\t\t\tif ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;\n\t\t\tif ( p === DstAlphaFactor ) return _gl.DST_ALPHA;\n\t\t\tif ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;\n\n\t\t\tif ( p === DstColorFactor ) return _gl.DST_COLOR;\n\t\t\tif ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;\n\t\t\tif ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;\n\n\t\t\tif ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||\n\t\t\t\tp === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;\n\t\t\t\t\tif ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||\n\t\t\t\tp === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;\n\t\t\t\t\tif ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === RGB_ETC1_Format ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_compressed_texture_etc1' );\n\n\t\t\t\tif ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;\n\n\t\t\t}\n\n\t\t\tif ( p === MinEquation || p === MaxEquation ) {\n\n\t\t\t\textension = extensions.get( 'EXT_blend_minmax' );\n\n\t\t\t\tif ( extension !== null ) {\n\n\t\t\t\t\tif ( p === MinEquation ) return extension.MIN_EXT;\n\t\t\t\t\tif ( p === MaxEquation ) return extension.MAX_EXT;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( p === UnsignedInt248Type ) {\n\n\t\t\t\textension = extensions.get( 'WEBGL_depth_texture' );\n\n\t\t\t\tif ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;\n\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t}\n\n\t}\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction FogExp2 ( color, density ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\t\tthis.density = ( density !== undefined ) ? density : 0.00025;\n\n\t}\n\n\tFogExp2.prototype.isFogExp2 = true;\n\n\tFogExp2.prototype.clone = function () {\n\n\t\treturn new FogExp2( this.color.getHex(), this.density );\n\n\t};\n\n\tFogExp2.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'FogExp2',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tdensity: this.density\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Fog ( color, near, far ) {\n\n\t\tthis.name = '';\n\n\t\tthis.color = new Color( color );\n\n\t\tthis.near = ( near !== undefined ) ? near : 1;\n\t\tthis.far = ( far !== undefined ) ? far : 1000;\n\n\t}\n\n\tFog.prototype.isFog = true;\n\n\tFog.prototype.clone = function () {\n\n\t\treturn new Fog( this.color.getHex(), this.near, this.far );\n\n\t};\n\n\tFog.prototype.toJSON = function ( meta ) {\n\n\t\treturn {\n\t\t\ttype: 'Fog',\n\t\t\tcolor: this.color.getHex(),\n\t\t\tnear: this.near,\n\t\t\tfar: this.far\n\t\t};\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Scene () {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Scene';\n\n\t\tthis.background = null;\n\t\tthis.fog = null;\n\t\tthis.overrideMaterial = null;\n\n\t\tthis.autoUpdate = true; // checked by the renderer\n\n\t}\n\n\tScene.prototype = Object.create( Object3D.prototype );\n\n\tScene.prototype.constructor = Scene;\n\n\tScene.prototype.copy = function ( source, recursive ) {\n\n\t\tObject3D.prototype.copy.call( this, source, recursive );\n\n\t\tif ( source.background !== null ) this.background = source.background.clone();\n\t\tif ( source.fog !== null ) this.fog = source.fog.clone();\n\t\tif ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone();\n\n\t\tthis.autoUpdate = source.autoUpdate;\n\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\n\t\treturn this;\n\n\t};\n\n\tScene.prototype.toJSON = function ( meta ) {\n\n\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\tif ( this.background !== null ) data.object.background = this.background.toJSON( meta );\n\t\tif ( this.fog !== null ) data.object.fog = this.fog.toJSON();\n\n\t\treturn data;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction LensFlare( texture, size, distance, blending, color ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.lensFlares = [];\n\n\t\tthis.positionScreen = new Vector3();\n\t\tthis.customUpdateCallback = undefined;\n\n\t\tif ( texture !== undefined ) {\n\n\t\t\tthis.add( texture, size, distance, blending, color );\n\n\t\t}\n\n\t}\n\n\tLensFlare.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LensFlare,\n\n\t\tisLensFlare: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.positionScreen.copy( source.positionScreen );\n\t\t\tthis.customUpdateCallback = source.customUpdateCallback;\n\n\t\t\tfor ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lensFlares.push( source.lensFlares[ i ] );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tadd: function ( texture, size, distance, blending, color, opacity ) {\n\n\t\t\tif ( size === undefined ) size = - 1;\n\t\t\tif ( distance === undefined ) distance = 0;\n\t\t\tif ( opacity === undefined ) opacity = 1;\n\t\t\tif ( color === undefined ) color = new Color( 0xffffff );\n\t\t\tif ( blending === undefined ) blending = NormalBlending;\n\n\t\t\tdistance = Math.min( distance, Math.max( 0, distance ) );\n\n\t\t\tthis.lensFlares.push( {\n\t\t\t\ttexture: texture,\t// THREE.Texture\n\t\t\t\tsize: size, \t\t// size in pixels (-1 = use texture.width)\n\t\t\t\tdistance: distance, \t// distance (0-1) from light source (0=at light source)\n\t\t\t\tx: 0, y: 0, z: 0,\t// screen position (-1 => 1) z = 0 is in front z = 1 is back\n\t\t\t\tscale: 1, \t\t// scale\n\t\t\t\trotation: 0, \t\t// rotation\n\t\t\t\topacity: opacity,\t// opacity\n\t\t\t\tcolor: color,\t\t// color\n\t\t\t\tblending: blending\t// blending\n\t\t\t} );\n\n\t\t},\n\n\t\t/*\n\t\t * Update lens flares update positions on all flares based on the screen position\n\t\t * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.\n\t\t */\n\n\t\tupdateLensFlares: function () {\n\n\t\t\tvar f, fl = this.lensFlares.length;\n\t\t\tvar flare;\n\t\t\tvar vecX = - this.positionScreen.x * 2;\n\t\t\tvar vecY = - this.positionScreen.y * 2;\n\n\t\t\tfor ( f = 0; f < fl; f ++ ) {\n\n\t\t\t\tflare = this.lensFlares[ f ];\n\n\t\t\t\tflare.x = this.positionScreen.x + vecX * flare.distance;\n\t\t\t\tflare.y = this.positionScreen.y + vecY * flare.distance;\n\n\t\t\t\tflare.wantedRotation = flare.x * Math.PI * 0.25;\n\t\t\t\tflare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t *\tuvOffset: new THREE.Vector2(),\n\t *\tuvScale: new THREE.Vector2()\n\t * }\n\t */\n\n\tfunction SpriteMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'SpriteMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\t\tthis.map = null;\n\n\t\tthis.rotation = 0;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tSpriteMaterial.prototype = Object.create( Material.prototype );\n\tSpriteMaterial.prototype.constructor = SpriteMaterial;\n\n\tSpriteMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.map = source.map;\n\n\t\tthis.rotation = source.rotation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Sprite( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Sprite';\n\n\t\tthis.material = ( material !== undefined ) ? material : new SpriteMaterial();\n\n\t}\n\n\tSprite.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Sprite,\n\n\t\tisSprite: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );\n\t\t\t\tvar guessSizeSq = this.scale.x * this.scale.y / 4;\n\n\t\t\t\tif ( distanceSq > guessSizeSq ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tintersects.push( {\n\n\t\t\t\t\tdistance: Math.sqrt( distanceSq ),\n\t\t\t\t\tpoint: this.position,\n\t\t\t\t\tface: null,\n\t\t\t\t\tobject: this\n\n\t\t\t\t} );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LOD() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'LOD';\n\n\t\tObject.defineProperties( this, {\n\t\t\tlevels: {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: []\n\t\t\t}\n\t\t} );\n\n\t}\n\n\n\tLOD.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: LOD,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source, false );\n\n\t\t\tvar levels = source.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tthis.addLevel( level.object.clone(), level.distance );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\taddLevel: function ( object, distance ) {\n\n\t\t\tif ( distance === undefined ) distance = 0;\n\n\t\t\tdistance = Math.abs( distance );\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\tif ( distance < levels[ l ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tlevels.splice( l, 0, { distance: distance, object: object } );\n\n\t\t\tthis.add( object );\n\n\t\t},\n\n\t\tgetObjectForDistance: function ( distance ) {\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tif ( distance < levels[ i ].distance ) {\n\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn levels[ i - 1 ].object;\n\n\t\t},\n\n\t\traycast: ( function () {\n\n\t\t\tvar matrixPosition = new Vector3();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tmatrixPosition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( matrixPosition );\n\n\t\t\t\tthis.getObjectForDistance( distance ).raycast( raycaster, intersects );\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tupdate: function () {\n\n\t\t\tvar v1 = new Vector3();\n\t\t\tvar v2 = new Vector3();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar levels = this.levels;\n\n\t\t\t\tif ( levels.length > 1 ) {\n\n\t\t\t\t\tv1.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\t\tv2.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\t\tvar distance = v1.distanceTo( v2 );\n\n\t\t\t\t\tlevels[ 0 ].object.visible = true;\n\n\t\t\t\t\tfor ( var i = 1, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tif ( distance >= levels[ i ].distance ) {\n\n\t\t\t\t\t\t\tlevels[ i - 1 ].object.visible = false;\n\t\t\t\t\t\t\tlevels[ i ].object.visible = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( ; i < l; i ++ ) {\n\n\t\t\t\t\t\tlevels[ i ].object.visible = false;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}(),\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.levels = [];\n\n\t\t\tvar levels = this.levels;\n\n\t\t\tfor ( var i = 0, l = levels.length; i < l; i ++ ) {\n\n\t\t\t\tvar level = levels[ i ];\n\n\t\t\t\tdata.object.levels.push( {\n\t\t\t\t\tobject: level.object.uuid,\n\t\t\t\t\tdistance: level.distance\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author michael guerrero / http://realitymeltdown.com\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Skeleton( bones, boneInverses, useVertexTexture ) {\n\n\t\tthis.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;\n\n\t\tthis.identityMatrix = new Matrix4();\n\n\t\t// copy the bone array\n\n\t\tbones = bones || [];\n\n\t\tthis.bones = bones.slice( 0 );\n\n\t\t// create a bone texture or an array of floats\n\n\t\tif ( this.useVertexTexture ) {\n\n\t\t\t// layout (1 matrix = 4 pixels)\n\t\t\t// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n\t\t\t// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)\n\t\t\t// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)\n\t\t\t// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)\n\t\t\t// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)\n\n\n\t\t\tvar size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix\n\t\t\tsize = _Math.nextPowerOfTwo( Math.ceil( size ) );\n\t\t\tsize = Math.max( size, 4 );\n\n\t\t\tthis.boneTextureWidth = size;\n\t\t\tthis.boneTextureHeight = size;\n\n\t\t\tthis.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel\n\t\t\tthis.boneTexture = new DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, RGBAFormat, FloatType );\n\n\t\t} else {\n\n\t\t\tthis.boneMatrices = new Float32Array( 16 * this.bones.length );\n\n\t\t}\n\n\t\t// use the supplied bone inverses or calculate the inverses\n\n\t\tif ( boneInverses === undefined ) {\n\n\t\t\tthis.calculateInverses();\n\n\t\t} else {\n\n\t\t\tif ( this.bones.length === boneInverses.length ) {\n\n\t\t\t\tthis.boneInverses = boneInverses.slice( 0 );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.Skeleton bonInverses is the wrong length.' );\n\n\t\t\t\tthis.boneInverses = [];\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\tthis.boneInverses.push( new Matrix4() );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tObject.assign( Skeleton.prototype, {\n\n\t\tcalculateInverses: function () {\n\n\t\t\tthis.boneInverses = [];\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tvar inverse = new Matrix4();\n\n\t\t\t\tif ( this.bones[ b ] ) {\n\n\t\t\t\t\tinverse.getInverse( this.bones[ b ].matrixWorld );\n\n\t\t\t\t}\n\n\t\t\t\tthis.boneInverses.push( inverse );\n\n\t\t\t}\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tvar bone;\n\n\t\t\t// recover the bind-time world matrices\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tbone.matrixWorld.getInverse( this.boneInverses[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// compute the local matrices, positions, rotations and scales\n\n\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\tbone = this.bones[ b ];\n\n\t\t\t\tif ( bone ) {\n\n\t\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\t\tbone.matrix.getInverse( bone.parent.matrixWorld );\n\t\t\t\t\t\tbone.matrix.multiply( bone.matrixWorld );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tbone.matrix.copy( bone.matrixWorld );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tbone.matrix.decompose( bone.position, bone.quaternion, bone.scale );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdate: ( function () {\n\n\t\t\tvar offsetMatrix = new Matrix4();\n\n\t\t\treturn function update() {\n\n\t\t\t\t// flatten bone matrices to array\n\n\t\t\t\tfor ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {\n\n\t\t\t\t\t// compute the offset between the current and the original transform\n\n\t\t\t\t\tvar matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix;\n\n\t\t\t\t\toffsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] );\n\t\t\t\t\toffsetMatrix.toArray( this.boneMatrices, b * 16 );\n\n\t\t\t\t}\n\n\t\t\t\tif ( this.useVertexTexture ) {\n\n\t\t\t\t\tthis.boneTexture.needsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )(),\n\n\t\tclone: function () {\n\n\t\t\treturn new Skeleton( this.bones, this.boneInverses, this.useVertexTexture );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction Bone() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Bone';\n\n\t}\n\n\tBone.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Bone,\n\n\t\tisBone: true\n\n\t} );\n\n\t/**\n\t * @author mikael emtinger / http://gomo.se/\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author ikerr / http://verold.com\n\t */\n\n\tfunction SkinnedMesh( geometry, material, useVertexTexture ) {\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.type = 'SkinnedMesh';\n\n\t\tthis.bindMode = \"attached\";\n\t\tthis.bindMatrix = new Matrix4();\n\t\tthis.bindMatrixInverse = new Matrix4();\n\n\t\t// init bones\n\n\t\t// TODO: remove bone creation as there is no reason (other than\n\t\t// convenience) for THREE.SkinnedMesh to do this.\n\n\t\tvar bones = [];\n\n\t\tif ( this.geometry && this.geometry.bones !== undefined ) {\n\n\t\t\tvar bone, gbone;\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tbone = new Bone();\n\t\t\t\tbones.push( bone );\n\n\t\t\t\tbone.name = gbone.name;\n\t\t\t\tbone.position.fromArray( gbone.pos );\n\t\t\t\tbone.quaternion.fromArray( gbone.rotq );\n\t\t\t\tif ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );\n\n\t\t\t}\n\n\t\t\tfor ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {\n\n\t\t\t\tgbone = this.geometry.bones[ b ];\n\n\t\t\t\tif ( gbone.parent !== - 1 && gbone.parent !== null &&\n\t\t\t\t\t\tbones[ gbone.parent ] !== undefined ) {\n\n\t\t\t\t\tbones[ gbone.parent ].add( bones[ b ] );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.add( bones[ b ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.normalizeSkinWeights();\n\n\t\tthis.updateMatrixWorld( true );\n\t\tthis.bind( new Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );\n\n\t}\n\n\n\tSkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {\n\n\t\tconstructor: SkinnedMesh,\n\n\t\tisSkinnedMesh: true,\n\n\t\tbind: function( skeleton, bindMatrix ) {\n\n\t\t\tthis.skeleton = skeleton;\n\n\t\t\tif ( bindMatrix === undefined ) {\n\n\t\t\t\tthis.updateMatrixWorld( true );\n\n\t\t\t\tthis.skeleton.calculateInverses();\n\n\t\t\t\tbindMatrix = this.matrixWorld;\n\n\t\t\t}\n\n\t\t\tthis.bindMatrix.copy( bindMatrix );\n\t\t\tthis.bindMatrixInverse.getInverse( bindMatrix );\n\n\t\t},\n\n\t\tpose: function () {\n\n\t\t\tthis.skeleton.pose();\n\n\t\t},\n\n\t\tnormalizeSkinWeights: function () {\n\n\t\t\tif ( this.geometry && this.geometry.isGeometry ) {\n\n\t\t\t\tfor ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {\n\n\t\t\t\t\tvar sw = this.geometry.skinWeights[ i ];\n\n\t\t\t\t\tvar scale = 1.0 / sw.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tsw.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tsw.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.geometry && this.geometry.isBufferGeometry ) {\n\n\t\t\t\tvar vec = new Vector4();\n\n\t\t\t\tvar skinWeight = this.geometry.attributes.skinWeight;\n\n\t\t\t\tfor ( var i = 0; i < skinWeight.count; i ++ ) {\n\n\t\t\t\t\tvec.x = skinWeight.getX( i );\n\t\t\t\t\tvec.y = skinWeight.getY( i );\n\t\t\t\t\tvec.z = skinWeight.getZ( i );\n\t\t\t\t\tvec.w = skinWeight.getW( i );\n\n\t\t\t\t\tvar scale = 1.0 / vec.lengthManhattan();\n\n\t\t\t\t\tif ( scale !== Infinity ) {\n\n\t\t\t\t\t\tvec.multiplyScalar( scale );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvec.set( 1, 0, 0, 0 ); // do something reasonable\n\n\t\t\t\t\t}\n\n\t\t\t\t\tskinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\tupdateMatrixWorld: function( force ) {\n\n\t\t\tMesh.prototype.updateMatrixWorld.call( this, true );\n\n\t\t\tif ( this.bindMode === \"attached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.matrixWorld );\n\n\t\t\t} else if ( this.bindMode === \"detached\" ) {\n\n\t\t\t\tthis.bindMatrixInverse.getInverse( this.bindMatrix );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );\n\n\t\t\t}\n\n\t\t},\n\n\t\tclone: function() {\n\n\t\t\treturn new this.constructor( this.geometry, this.material, this.skeleton.useVertexTexture ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t * linecap: \"round\",\n\t * linejoin: \"round\"\n\t * }\n\t */\n\n\tfunction LineBasicMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineBasicMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\t\tthis.linecap = 'round';\n\t\tthis.linejoin = 'round';\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineBasicMaterial.prototype = Object.create( Material.prototype );\n\tLineBasicMaterial.prototype.constructor = LineBasicMaterial;\n\n\tLineBasicMaterial.prototype.isLineBasicMaterial = true;\n\n\tLineBasicMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\t\tthis.linecap = source.linecap;\n\t\tthis.linejoin = source.linejoin;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Line( geometry, material, mode ) {\n\n\t\tif ( mode === 1 ) {\n\n\t\t\tconsole.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );\n\t\t\treturn new LineSegments( geometry, material );\n\n\t\t}\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Line';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tLine.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Line,\n\n\t\tisLine: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar precision = raycaster.linePrecision;\n\t\t\t\tvar precisionSq = precision * precision;\n\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar vStart = new Vector3();\n\t\t\t\tvar vEnd = new Vector3();\n\t\t\t\tvar interSegment = new Vector3();\n\t\t\t\tvar interRay = new Vector3();\n\t\t\t\tvar step = (this && this.isLineSegments) ? 2 : 1;\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, l = indices.length - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\t\t\t\t\t\t\tvar b = indices[ i + 1 ];\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, a * 3 );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, b * 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) {\n\n\t\t\t\t\t\t\tvStart.fromArray( positions, 3 * i );\n\t\t\t\t\t\t\tvEnd.fromArray( positions, 3 * i + 3 );\n\n\t\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment );\n\n\t\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( geometry.isGeometry ) {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\t\t\t\t\tvar nbVertices = vertices.length;\n\n\t\t\t\t\tfor ( var i = 0; i < nbVertices - 1; i += step ) {\n\n\t\t\t\t\t\tvar distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );\n\n\t\t\t\t\t\tif ( distSq > precisionSq ) continue;\n\n\t\t\t\t\t\tinterRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( interRay );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) continue;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\t\t\t\tpoint: interSegment.clone().applyMatrix4( this.matrixWorld ),\n\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tfaceIndex: null,\n\t\t\t\t\t\t\tobject: this\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LineSegments( geometry, material ) {\n\n\t\tLine.call( this, geometry, material );\n\n\t\tthis.type = 'LineSegments';\n\n\t}\n\n\tLineSegments.prototype = Object.assign( Object.create( Line.prototype ), {\n\n\t\tconstructor: LineSegments,\n\n\t\tisLineSegments: true\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t * map: new THREE.Texture( ),\n\t *\n\t * size: ,\n\t * sizeAttenuation: \n\t * }\n\t */\n\n\tfunction PointsMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'PointsMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.map = null;\n\n\t\tthis.size = 1;\n\t\tthis.sizeAttenuation = true;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tPointsMaterial.prototype = Object.create( Material.prototype );\n\tPointsMaterial.prototype.constructor = PointsMaterial;\n\n\tPointsMaterial.prototype.isPointsMaterial = true;\n\n\tPointsMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.size = source.size;\n\t\tthis.sizeAttenuation = source.sizeAttenuation;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Points( geometry, material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Points';\n\n\t\tthis.geometry = geometry !== undefined ? geometry : new BufferGeometry();\n\t\tthis.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } );\n\n\t}\n\n\tPoints.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Points,\n\n\t\tisPoints: true,\n\n\t\traycast: ( function () {\n\n\t\t\tvar inverseMatrix = new Matrix4();\n\t\t\tvar ray = new Ray();\n\t\t\tvar sphere = new Sphere();\n\n\t\t\treturn function raycast( raycaster, intersects ) {\n\n\t\t\t\tvar object = this;\n\t\t\t\tvar geometry = this.geometry;\n\t\t\t\tvar matrixWorld = this.matrixWorld;\n\t\t\t\tvar threshold = raycaster.params.Points.threshold;\n\n\t\t\t\t// Checking boundingSphere distance to ray\n\n\t\t\t\tif ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();\n\n\t\t\t\tsphere.copy( geometry.boundingSphere );\n\t\t\t\tsphere.applyMatrix4( matrixWorld );\n\n\t\t\t\tif ( raycaster.ray.intersectsSphere( sphere ) === false ) return;\n\n\t\t\t\t//\n\n\t\t\t\tinverseMatrix.getInverse( matrixWorld );\n\t\t\t\tray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );\n\n\t\t\t\tvar localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );\n\t\t\t\tvar localThresholdSq = localThreshold * localThreshold;\n\t\t\t\tvar position = new Vector3();\n\n\t\t\t\tfunction testPoint( point, index ) {\n\n\t\t\t\t\tvar rayPointDistanceSq = ray.distanceSqToPoint( point );\n\n\t\t\t\t\tif ( rayPointDistanceSq < localThresholdSq ) {\n\n\t\t\t\t\t\tvar intersectPoint = ray.closestPointToPoint( point );\n\t\t\t\t\t\tintersectPoint.applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tvar distance = raycaster.ray.origin.distanceTo( intersectPoint );\n\n\t\t\t\t\t\tif ( distance < raycaster.near || distance > raycaster.far ) return;\n\n\t\t\t\t\t\tintersects.push( {\n\n\t\t\t\t\t\t\tdistance: distance,\n\t\t\t\t\t\t\tdistanceToRay: Math.sqrt( rayPointDistanceSq ),\n\t\t\t\t\t\t\tpoint: intersectPoint.clone(),\n\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\tface: null,\n\t\t\t\t\t\t\tobject: object\n\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\t\t\tvar index = geometry.index;\n\t\t\t\t\tvar attributes = geometry.attributes;\n\t\t\t\t\tvar positions = attributes.position.array;\n\n\t\t\t\t\tif ( index !== null ) {\n\n\t\t\t\t\t\tvar indices = index.array;\n\n\t\t\t\t\t\tfor ( var i = 0, il = indices.length; i < il; i ++ ) {\n\n\t\t\t\t\t\t\tvar a = indices[ i ];\n\n\t\t\t\t\t\t\tposition.fromArray( positions, a * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, a );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( var i = 0, l = positions.length / 3; i < l; i ++ ) {\n\n\t\t\t\t\t\t\tposition.fromArray( positions, i * 3 );\n\n\t\t\t\t\t\t\ttestPoint( position, i );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tvar vertices = geometry.vertices;\n\n\t\t\t\t\tfor ( var i = 0, l = vertices.length; i < l; i ++ ) {\n\n\t\t\t\t\t\ttestPoint( vertices[ i ], i );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}() ),\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor( this.geometry, this.material ).copy( this );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Group() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Group';\n\n\t}\n\n\tGroup.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Group\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.generateMipmaps = false;\n\n\t\tvar scope = this;\n\n\t\tfunction update() {\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\tif ( video.readyState >= video.HAVE_CURRENT_DATA ) {\n\n\t\t\t\tscope.needsUpdate = true;\n\n\t\t\t}\n\n\t\t}\n\n\t\tupdate();\n\n\t}\n\n\tVideoTexture.prototype = Object.create( Texture.prototype );\n\tVideoTexture.prototype.constructor = VideoTexture;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );\n\n\t\tthis.image = { width: width, height: height };\n\t\tthis.mipmaps = mipmaps;\n\n\t\t// no flipping for cube textures\n\t\t// (also flipping doesn't work for compressed textures )\n\n\t\tthis.flipY = false;\n\n\t\t// can't generate mipmaps for compressed textures\n\t\t// mips must be embedded in DDS files\n\n\t\tthis.generateMipmaps = false;\n\n\t}\n\n\tCompressedTexture.prototype = Object.create( Texture.prototype );\n\tCompressedTexture.prototype.constructor = CompressedTexture;\n\n\tCompressedTexture.prototype.isCompressedTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {\n\n\t\tTexture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.needsUpdate = true;\n\n\t}\n\n\tCanvasTexture.prototype = Object.create( Texture.prototype );\n\tCanvasTexture.prototype.constructor = CanvasTexture;\n\n\t/**\n\t * @author Matt DesLauriers / @mattdesl\n\t * @author atix / arthursilber.de\n\t */\n\n\tfunction DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {\n\n\t\tformat = format !== undefined ? format : DepthFormat;\n\n\t\tif ( format !== DepthFormat && format !== DepthStencilFormat ) {\n\n\t\t\tthrow new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' )\n\n\t\t}\n\n\t\tif ( type === undefined && format === DepthFormat ) type = UnsignedShortType;\n\t\tif ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;\n\n\t\tTexture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );\n\n\t\tthis.image = { width: width, height: height };\n\n\t\tthis.magFilter = magFilter !== undefined ? magFilter : NearestFilter;\n\t\tthis.minFilter = minFilter !== undefined ? minFilter : NearestFilter;\n\n\t\tthis.flipY = false;\n\t\tthis.generateMipmaps\t= false;\n\n\t}\n\n\tDepthTexture.prototype = Object.create( Texture.prototype );\n\tDepthTexture.prototype.constructor = DepthTexture;\n\tDepthTexture.prototype.isDepthTexture = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction WireframeGeometry( geometry ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'WireframeGeometry';\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar i, j, l, o, ol;\n\t\tvar edge = [ 0, 0 ], edges = {}, e;\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\t\tvar vertex;\n\n\t\t// different logic for Geometry and BufferGeometry\n\n\t\tif ( geometry && geometry.isGeometry ) {\n\n\t\t\t// create a data structure that contains all edges without duplicates\n\n\t\t\tvar faces = geometry.faces;\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// generate vertices\n\n\t\t\tfor ( key in edges ) {\n\n\t\t\t\te = edges[ key ];\n\n\t\t\t\tvertex = geometry.vertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = geometry.vertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t} else if ( geometry && geometry.isBufferGeometry ) {\n\n\t\t\tvar position, indices, groups;\n\t\t\tvar group, start, count;\n\t\t\tvar index1, index2;\n\n\t\t\tvertex = new Vector3();\n\n\t\t\tif ( geometry.index !== null ) {\n\n\t\t\t\t// indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\t\t\t\tindices = geometry.index;\n\t\t\t\tgroups = geometry.groups;\n\n\t\t\t\tif ( groups.length === 0 ) {\n\n\t\t\t\t\tgeometry.addGroup( 0, indices.count );\n\n\t\t\t\t}\n\n\t\t\t\t// create a data structure that contains all eges without duplicates\n\n\t\t\t\tfor ( o = 0, ol = groups.length; o < ol; ++ o ) {\n\n\t\t\t\t\tgroup = groups[ o ];\n\n\t\t\t\t\tstart = group.start;\n\t\t\t\t\tcount = group.count;\n\n\t\t\t\t\tfor ( i = start, l = ( start + count ); i < l; i += 3 ) {\n\n\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\tedge[ 0 ] = indices.getX( i + j );\n\t\t\t\t\t\t\tedge[ 1 ] = indices.getX( i + ( j + 1 ) % 3 );\n\t\t\t\t\t\t\tedge.sort( sortFunction ); // sorting prevents duplicates\n\n\t\t\t\t\t\t\tkey = edge.toString();\n\n\t\t\t\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// generate vertices\n\n\t\t\t\tfor ( key in edges ) {\n\n\t\t\t\t\te = edges[ key ];\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index1 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\tvertex.fromBufferAttribute( position, e.index2 );\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// non-indexed BufferGeometry\n\n\t\t\t\tposition = geometry.attributes.position;\n\n\t\t\t\tfor ( i = 0, l = ( position.count / 3 ); i < l; i ++ ) {\n\n\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t// three edges per triangle, an edge is represented as (index1, index2)\n\t\t\t\t\t\t// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)\n\n\t\t\t\t\t\tindex1 = 3 * i + j;\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index1 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t\tindex2 = 3 * i + ( ( j + 1 ) % 3 );\n\t\t\t\t\t\tvertex.fromBufferAttribute( position, index2 );\n\t\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tWireframeGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tWireframeGeometry.prototype.constructor = WireframeGeometry;\n\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricGeometry( func, slices, stacks ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ParametricGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tParametricGeometry.prototype = Object.create( Geometry.prototype );\n\tParametricGeometry.prototype.constructor = ParametricGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Parametric Surfaces Geometry\n\t * based on the brilliant article by @prideout http://prideout.net/blog/?p=44\n\t */\n\n\tfunction ParametricBufferGeometry( func, slices, stacks ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ParametricBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tfunc: func,\n\t\t\tslices: slices,\n\t\t\tstacks: stacks\n\t\t};\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tvar sliceCount = slices + 1;\n\n\t\tfor ( i = 0; i <= stacks; i ++ ) {\n\n\t\t\tvar v = i / stacks;\n\n\t\t\tfor ( j = 0; j <= slices; j ++ ) {\n\n\t\t\t\tvar u = j / slices;\n\n\t\t\t\tvar p = func( u, v );\n\t\t\t\tvertices.push( p.x, p.y, p.z );\n\n\t\t\t\tuvs.push( u, v );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( i = 0; i < stacks; i ++ ) {\n\n\t\t\tfor ( j = 0; j < slices; j ++ ) {\n\n\t\t\t\tvar a = i * sliceCount + j;\n\t\t\t\tvar b = i * sliceCount + j + 1;\n\t\t\t\tvar c = ( i + 1 ) * sliceCount + j + 1;\n\t\t\t\tvar d = ( i + 1 ) * sliceCount + j;\n\n\t\t\t\t// faces one and two\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t}\n\n\tParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;\n\n\t/**\n\t * @author clockworkgeek / https://github.com/clockworkgeek\n\t * @author timothypratley / https://github.com/timothypratley\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction PolyhedronGeometry( vertices, indices, radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tPolyhedronGeometry.prototype = Object.create( Geometry.prototype );\n\tPolyhedronGeometry.prototype.constructor = PolyhedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction PolyhedronBufferGeometry( vertices, indices, radius, detail ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'PolyhedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tvertices: vertices,\n\t\t\tindices: indices,\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tradius = radius || 1;\n\t\tdetail = detail || 0;\n\n\t\t// default buffer data\n\n\t\tvar vertexBuffer = [];\n\t\tvar uvBuffer = [];\n\n\t\t// the subdivision creates the vertex buffer data\n\n\t\tsubdivide( detail );\n\n\t\t// all vertices should lie on a conceptual sphere with a given radius\n\n\t\tappplyRadius( radius );\n\n\t\t// finally, create the uv data\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );\n\t\tthis.normalizeNormals();\n\n\t\t// helper functions\n\n\t\tfunction subdivide( detail ) {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\t// iterate over all faces and apply a subdivison with the given detail value\n\n\t\t\tfor ( var i = 0; i < indices.length; i += 3 ) {\n\n\t\t\t\t// get the vertices of the face\n\n\t\t\t\tgetVertexByIndex( indices[ i + 0 ], a );\n\t\t\t\tgetVertexByIndex( indices[ i + 1 ], b );\n\t\t\t\tgetVertexByIndex( indices[ i + 2 ], c );\n\n\t\t\t\t// perform subdivision\n\n\t\t\t\tsubdivideFace( a, b, c, detail );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction subdivideFace( a, b, c, detail ) {\n\n\t\t\tvar cols = Math.pow( 2, detail );\n\n\t\t\t// we use this multidimensional array as a data structure for creating the subdivision\n\n\t\t\tvar v = [];\n\n\t\t\tvar i, j;\n\n\t\t\t// construct all of the vertices for this subdivision\n\n\t\t\tfor ( i = 0; i <= cols; i ++ ) {\n\n\t\t\t\tv[ i ] = [];\n\n\t\t\t\tvar aj = a.clone().lerp( c, i / cols );\n\t\t\t\tvar bj = b.clone().lerp( c, i / cols );\n\n\t\t\t\tvar rows = cols - i;\n\n\t\t\t\tfor ( j = 0; j <= rows; j ++ ) {\n\n\t\t\t\t\tif ( j === 0 && i === cols ) {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv[ i ][ j ] = aj.clone().lerp( bj, j / rows );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// construct all of the faces\n\n\t\t\tfor ( i = 0; i < cols; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {\n\n\t\t\t\t\tvar k = Math.floor( j / 2 );\n\n\t\t\t\t\tif ( j % 2 === 0 ) {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\t\t\t\t\t\tpushVertex( v[ i ][ k ] );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tpushVertex( v[ i ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k + 1 ] );\n\t\t\t\t\t\tpushVertex( v[ i + 1 ][ k ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction appplyRadius( radius ) {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\t// iterate over the entire buffer and apply the radius to each vertex\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvertex.normalize().multiplyScalar( radius );\n\n\t\t\t\tvertexBuffer[ i + 0 ] = vertex.x;\n\t\t\t\tvertexBuffer[ i + 1 ] = vertex.y;\n\t\t\t\tvertexBuffer[ i + 2 ] = vertex.z;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tfor ( var i = 0; i < vertexBuffer.length; i += 3 ) {\n\n\t\t\t\tvertex.x = vertexBuffer[ i + 0 ];\n\t\t\t\tvertex.y = vertexBuffer[ i + 1 ];\n\t\t\t\tvertex.z = vertexBuffer[ i + 2 ];\n\n\t\t\t\tvar u = azimuth( vertex ) / 2 / Math.PI + 0.5;\n\t\t\t\tvar v = inclination( vertex ) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push( u, 1 - v );\n\n\t\t\t}\n\n\t\t\tcorrectUVs();\n\n\t\t\tcorrectSeam();\n\n\t\t}\n\n\t\tfunction correctSeam() {\n\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor ( var i = 0; i < uvBuffer.length; i += 6 ) {\n\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tvar x0 = uvBuffer[ i + 0 ];\n\t\t\t\tvar x1 = uvBuffer[ i + 2 ];\n\t\t\t\tvar x2 = uvBuffer[ i + 4 ];\n\n\t\t\t\tvar max = Math.max( x0, x1, x2 );\n\t\t\t\tvar min = Math.min( x0, x1, x2 );\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif ( max > 0.9 && min < 0.1 ) {\n\n\t\t\t\t\tif ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;\n\t\t\t\t\tif ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;\n\t\t\t\t\tif ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction pushVertex( vertex ) {\n\n\t\t\tvertexBuffer.push( vertex.x, vertex.y, vertex.z );\n\n\t\t}\n\n\t\tfunction getVertexByIndex( index, vertex ) {\n\n\t\t\tvar stride = index * 3;\n\n\t\t\tvertex.x = vertices[ stride + 0 ];\n\t\t\tvertex.y = vertices[ stride + 1 ];\n\t\t\tvertex.z = vertices[ stride + 2 ];\n\n\t\t}\n\n\t\tfunction correctUVs() {\n\n\t\t\tvar a = new Vector3();\n\t\t\tvar b = new Vector3();\n\t\t\tvar c = new Vector3();\n\n\t\t\tvar centroid = new Vector3();\n\n\t\t\tvar uvA = new Vector2();\n\t\t\tvar uvB = new Vector2();\n\t\t\tvar uvC = new Vector2();\n\n\t\t\tfor ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {\n\n\t\t\t\ta.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );\n\t\t\t\tb.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );\n\t\t\t\tc.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );\n\n\t\t\t\tuvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );\n\t\t\t\tuvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );\n\t\t\t\tuvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );\n\n\t\t\t\tcentroid.copy( a ).add( b ).add( c ).divideScalar( 3 );\n\n\t\t\t\tvar azi = azimuth( centroid );\n\n\t\t\t\tcorrectUV( uvA, j + 0, a, azi );\n\t\t\t\tcorrectUV( uvB, j + 2, b, azi );\n\t\t\t\tcorrectUV( uvC, j + 4, c, azi );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction correctUV( uv, stride, vector, azimuth ) {\n\n\t\t\tif ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = uv.x - 1;\n\n\t\t\t}\n\n\t\t\tif ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {\n\n\t\t\t\tuvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\n\t\tfunction azimuth( vector ) {\n\n\t\t\treturn Math.atan2( vector.z, - vector.x );\n\n\t\t}\n\n\n\t\t// Angle above the XZ plane.\n\n\t\tfunction inclination( vector ) {\n\n\t\t\treturn Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );\n\n\t\t}\n\n\t}\n\n\tPolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tPolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction TetrahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TetrahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTetrahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tTetrahedronGeometry.prototype.constructor = TetrahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TetrahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'TetrahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tTetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tTetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction OctahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'OctahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tOctahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tOctahedronGeometry.prototype.constructor = OctahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction OctahedronBufferGeometry( radius, detail ) {\n\n\t\tvar vertices = [\n\t\t\t1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 1, 0, 0, - 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'OctahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tOctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tOctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;\n\n\t/**\n\t * @author timothypratley / https://github.com/timothypratley\n\t */\n\n\tfunction IcosahedronGeometry( radius, detail ) {\n\n\t \tGeometry.call( this );\n\n\t\tthis.type = 'IcosahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tIcosahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tIcosahedronGeometry.prototype.constructor = IcosahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction IcosahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\n\t\tvar vertices = [\n\t\t\t- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,\n\t\t\t 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,\n\t\t\t t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,\n\t\t\t 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,\n\t\t\t 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,\n\t\t\t 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'IcosahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tIcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tIcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;\n\n\t/**\n\t * @author Abe Pazos / https://hamoid.com\n\t */\n\n\tfunction DodecahedronGeometry( radius, detail ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'DodecahedronGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t\tthis.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tDodecahedronGeometry.prototype = Object.create( Geometry.prototype );\n\tDodecahedronGeometry.prototype.constructor = DodecahedronGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction DodecahedronBufferGeometry( radius, detail ) {\n\n\t\tvar t = ( 1 + Math.sqrt( 5 ) ) / 2;\n\t\tvar r = 1 / t;\n\n\t\tvar vertices = [\n\n\t\t\t// (±1, ±1, ±1)\n\t\t\t- 1, - 1, - 1, - 1, - 1, 1,\n\t\t\t- 1, 1, - 1, - 1, 1, 1,\n\t\t\t 1, - 1, - 1, 1, - 1, 1,\n\t\t\t 1, 1, - 1, 1, 1, 1,\n\n\t\t\t// (0, ±1/φ, ±φ)\n\t\t\t 0, - r, - t, 0, - r, t,\n\t\t\t 0, r, - t, 0, r, t,\n\n\t\t\t// (±1/φ, ±φ, 0)\n\t\t\t- r, - t, 0, - r, t, 0,\n\t\t\t r, - t, 0, r, t, 0,\n\n\t\t\t// (±φ, 0, ±1/φ)\n\t\t\t- t, 0, - r, t, 0, - r,\n\t\t\t- t, 0, r, t, 0, r\n\t\t];\n\n\t\tvar indices = [\n\t\t\t 3, 11, 7, 3, 7, 15, 3, 15, 13,\n\t\t\t 7, 19, 17, 7, 17, 6, 7, 6, 15,\n\t\t\t17, 4, 8, 17, 8, 10, 17, 10, 6,\n\t\t\t 8, 0, 16, 8, 16, 2, 8, 2, 10,\n\t\t\t 0, 12, 1, 0, 1, 18, 0, 18, 16,\n\t\t\t 6, 10, 2, 6, 2, 13, 6, 13, 15,\n\t\t\t 2, 16, 18, 2, 18, 3, 2, 3, 13,\n\t\t\t18, 1, 9, 18, 9, 11, 18, 11, 3,\n\t\t\t 4, 14, 12, 4, 12, 0, 4, 0, 8,\n\t\t\t11, 9, 5, 11, 5, 19, 11, 19, 7,\n\t\t\t19, 5, 14, 19, 14, 4, 19, 4, 17,\n\t\t\t 1, 12, 14, 1, 14, 5, 1, 5, 9\n\t\t];\n\n\t\tPolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );\n\n\t\tthis.type = 'DodecahedronBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tdetail: detail\n\t\t};\n\n\t}\n\n\tDodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );\n\tDodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode / https://github.com/oosmoxiecode\n\t * @author WestLangley / https://github.com/WestLangley\n\t * @author zz85 / https://github.com/zz85\n\t * @author miningold / https://github.com/miningold\n\t * @author jonobr1 / https://github.com/jonobr1\n\t *\n\t * Creates a tube which extrudes along a 3d spline.\n\t */\n\n\tfunction TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TubeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\tif ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );\n\n\t\tvar bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = bufferGeometry.tangents;\n\t\tthis.normals = bufferGeometry.normals;\n\t\tthis.binormals = bufferGeometry.binormals;\n\n\t\t// create geometry\n\n\t\tthis.fromBufferGeometry( bufferGeometry );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTubeGeometry.prototype = Object.create( Geometry.prototype );\n\tTubeGeometry.prototype.constructor = TubeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TubeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpath: path,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradius: radius,\n\t\t\tradialSegments: radialSegments,\n\t\t\tclosed: closed\n\t\t};\n\n\t\ttubularSegments = tubularSegments || 64;\n\t\tradius = radius || 1;\n\t\tradialSegments = radialSegments || 8;\n\t\tclosed = closed || false;\n\n\t\tvar frames = path.computeFrenetFrames( tubularSegments, closed );\n\n\t\t// expose internals\n\n\t\tthis.tangents = frames.tangents;\n\t\tthis.normals = frames.normals;\n\t\tthis.binormals = frames.binormals;\n\n\t\t// helper variables\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar i, j;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\t\tvar indices = [];\n\n\t\t// create buffer data\n\n\t\tgenerateBufferData();\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// functions\n\n\t\tfunction generateBufferData() {\n\n\t\t\tfor ( i = 0; i < tubularSegments; i ++ ) {\n\n\t\t\t\tgenerateSegment( i );\n\n\t\t\t}\n\n\t\t\t// if the geometry is not closed, generate the last row of vertices and normals\n\t\t\t// at the regular position on the given path\n\t\t\t//\n\t\t\t// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)\n\n\t\t\tgenerateSegment( ( closed === false ) ? tubularSegments : 0 );\n\n\t\t\t// uvs are generated in a separate function.\n\t\t\t// this makes it easy compute correct values for closed geometries\n\n\t\t\tgenerateUVs();\n\n\t\t\t// finally create faces\n\n\t\t\tgenerateIndices();\n\n\t\t}\n\n\t\tfunction generateSegment( i ) {\n\n\t\t\t// we use getPointAt to sample evenly distributed points from the given path\n\n\t\t\tvar P = path.getPointAt( i / tubularSegments );\n\n\t\t\t// retrieve corresponding normal and binormal\n\n\t\t\tvar N = frames.normals[ i ];\n\t\t\tvar B = frames.binormals[ i ];\n\n\t\t\t// generate normals and vertices for the current segment\n\n\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\tvar sin = Math.sin( v );\n\t\t\t\tvar cos = - Math.cos( v );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.x = ( cos * N.x + sin * B.x );\n\t\t\t\tnormal.y = ( cos * N.y + sin * B.y );\n\t\t\t\tnormal.z = ( cos * N.z + sin * B.z );\n\t\t\t\tnormal.normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = P.x + radius * normal.x;\n\t\t\t\tvertex.y = P.y + radius * normal.y;\n\t\t\t\tvertex.z = P.z + radius * normal.z;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateIndices() {\n\n\t\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction generateUVs() {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\t\t\tuv.x = i / tubularSegments;\n\t\t\t\t\tuv.y = j / radialSegments;\n\n\t\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tTubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTubeBufferGeometry.prototype.constructor = TubeBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t */\n\n\tfunction TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tif ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );\n\n\t\tthis.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tTorusKnotGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusKnotGeometry.prototype.constructor = TorusKnotGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t * see: http://www.blackpawn.com/texts/pqtorus/\n\t */\n\n\tfunction TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusKnotBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tradialSegments: radialSegments,\n\t\t\tp: p,\n\t\t\tq: q\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 64;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\tp = p || 2;\n\t\tq = q || 3;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, j;\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\tvar P1 = new Vector3();\n\t\tvar P2 = new Vector3();\n\n\t\tvar B = new Vector3();\n\t\tvar T = new Vector3();\n\t\tvar N = new Vector3();\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( i = 0; i <= tubularSegments; ++ i ) {\n\n\t\t\t// the radian \"u\" is used to calculate the position on the torus curve of the current tubular segement\n\n\t\t\tvar u = i / tubularSegments * p * Math.PI * 2;\n\n\t\t\t// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.\n\t\t\t// these points are used to create a special \"coordinate space\", which is necessary to calculate the correct vertex positions\n\n\t\t\tcalculatePositionOnCurve( u, p, q, radius, P1 );\n\t\t\tcalculatePositionOnCurve( u + 0.01, p, q, radius, P2 );\n\n\t\t\t// calculate orthonormal basis\n\n\t\t\tT.subVectors( P2, P1 );\n\t\t\tN.addVectors( P2, P1 );\n\t\t\tB.crossVectors( T, N );\n\t\t\tN.crossVectors( B, T );\n\n\t\t\t// normalize B, N. T can be ignored, we don't use it\n\n\t\t\tB.normalize();\n\t\t\tN.normalize();\n\n\t\t\tfor ( j = 0; j <= radialSegments; ++ j ) {\n\n\t\t\t\t// now calculate the vertices. they are nothing more than an extrusion of the torus curve.\n\t\t\t\t// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.\n\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\t\t\t\tvar cx = - tube * Math.cos( v );\n\t\t\t\tvar cy = tube * Math.sin( v );\n\n\t\t\t\t// now calculate the final vertex position.\n\t\t\t\t// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve\n\n\t\t\t\tvertex.x = P1.x + ( cx * N.x + cy * B.x );\n\t\t\t\tvertex.y = P1.y + ( cx * N.y + cy * B.y );\n\t\t\t\tvertex.z = P1.z + ( cx * N.z + cy * B.z );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)\n\n\t\t\t\tnormal.subVectors( vertex, P1 ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= tubularSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= radialSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );\n\t\t\t\tvar b = ( radialSegments + 1 ) * j + ( i - 1 );\n\t\t\t\tvar c = ( radialSegments + 1 ) * j + i;\n\t\t\t\tvar d = ( radialSegments + 1 ) * ( j - 1 ) + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// this function calculates the current position on the torus curve\n\n\t\tfunction calculatePositionOnCurve( u, p, q, radius, position ) {\n\n\t\t\tvar cu = Math.cos( u );\n\t\t\tvar su = Math.sin( u );\n\t\t\tvar quOverP = q / p * u;\n\t\t\tvar cs = Math.cos( quOverP );\n\n\t\t\tposition.x = radius * ( 2 + cs ) * 0.5 * cu;\n\t\t\tposition.y = radius * ( 2 + cs ) * su * 0.5;\n\t\t\tposition.z = radius * Math.sin( quOverP ) * 0.5;\n\n\t\t}\n\n\t}\n\n\tTorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;\n\n\t/**\n\t * @author oosmoxiecode\n\t * @author mrdoob / http://mrdoob.com/\n\t * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888\n\t */\n\n\tfunction TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'TorusGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tthis.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );\n\n\t}\n\n\tTorusGeometry.prototype = Object.create( Geometry.prototype );\n\tTorusGeometry.prototype.constructor = TorusGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'TorusBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\ttube: tube,\n\t\t\tradialSegments: radialSegments,\n\t\t\ttubularSegments: tubularSegments,\n\t\t\tarc: arc\n\t\t};\n\n\t\tradius = radius || 100;\n\t\ttube = tube || 40;\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\ttubularSegments = Math.floor( tubularSegments ) || 6;\n\t\tarc = arc || Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar center = new Vector3();\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= tubularSegments; i ++ ) {\n\n\t\t\t\tvar u = i / tubularSegments * arc;\n\t\t\t\tvar v = j / radialSegments * Math.PI * 2;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );\n\t\t\t\tvertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );\n\t\t\t\tvertex.z = tube * Math.sin( v );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tcenter.x = radius * Math.cos( u );\n\t\t\t\tcenter.y = radius * Math.sin( u );\n\t\t\t\tnormal.subVectors( vertex, center ).normalize();\n\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( i / tubularSegments );\n\t\t\t\tuvs.push( j / radialSegments );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate indices\n\n\t\tfor ( j = 1; j <= radialSegments; j ++ ) {\n\n\t\t\tfor ( i = 1; i <= tubularSegments; i ++ ) {\n\n\t\t\t\t// indices\n\n\t\t\t\tvar a = ( tubularSegments + 1 ) * j + i - 1;\n\t\t\t\tvar b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;\n\t\t\t\tvar c = ( tubularSegments + 1 ) * ( j - 1 ) + i;\n\t\t\t\tvar d = ( tubularSegments + 1 ) * j + i;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tTorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tTorusBufferGeometry.prototype.constructor = TorusBufferGeometry;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t */\n\n\tvar ShapeUtils = {\n\n\t\t// calculate area of the contour polygon\n\n\t\tarea: function ( contour ) {\n\n\t\t\tvar n = contour.length;\n\t\t\tvar a = 0.0;\n\n\t\t\tfor ( var p = n - 1, q = 0; q < n; p = q ++ ) {\n\n\t\t\t\ta += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;\n\n\t\t\t}\n\n\t\t\treturn a * 0.5;\n\n\t\t},\n\n\t\ttriangulate: ( function () {\n\n\t\t\t/**\n\t\t\t * This code is a quick port of code written in C++ which was submitted to\n\t\t\t * flipcode.com by John W. Ratcliff // July 22, 2000\n\t\t\t * See original code and more information here:\n\t\t\t * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml\n\t\t\t *\n\t\t\t * ported to actionscript by Zevan Rosser\n\t\t\t * www.actionsnippet.com\n\t\t\t *\n\t\t\t * ported to javascript by Joshua Koo\n\t\t\t * http://www.lab4games.net/zz85/blog\n\t\t\t *\n\t\t\t */\n\n\t\t\tfunction snip( contour, u, v, w, n, verts ) {\n\n\t\t\t\tvar p;\n\t\t\t\tvar ax, ay, bx, by;\n\t\t\t\tvar cx, cy, px, py;\n\n\t\t\t\tax = contour[ verts[ u ] ].x;\n\t\t\t\tay = contour[ verts[ u ] ].y;\n\n\t\t\t\tbx = contour[ verts[ v ] ].x;\n\t\t\t\tby = contour[ verts[ v ] ].y;\n\n\t\t\t\tcx = contour[ verts[ w ] ].x;\n\t\t\t\tcy = contour[ verts[ w ] ].y;\n\n\t\t\t\tif ( ( bx - ax ) * ( cy - ay ) - ( by - ay ) * ( cx - ax ) <= 0 ) return false;\n\n\t\t\t\tvar aX, aY, bX, bY, cX, cY;\n\t\t\t\tvar apx, apy, bpx, bpy, cpx, cpy;\n\t\t\t\tvar cCROSSap, bCROSScp, aCROSSbp;\n\n\t\t\t\taX = cx - bx; aY = cy - by;\n\t\t\t\tbX = ax - cx; bY = ay - cy;\n\t\t\t\tcX = bx - ax; cY = by - ay;\n\n\t\t\t\tfor ( p = 0; p < n; p ++ ) {\n\n\t\t\t\t\tpx = contour[ verts[ p ] ].x;\n\t\t\t\t\tpy = contour[ verts[ p ] ].y;\n\n\t\t\t\t\tif ( ( ( px === ax ) && ( py === ay ) ) ||\n\t\t\t\t\t\t ( ( px === bx ) && ( py === by ) ) ||\n\t\t\t\t\t\t ( ( px === cx ) && ( py === cy ) ) )\tcontinue;\n\n\t\t\t\t\tapx = px - ax; apy = py - ay;\n\t\t\t\t\tbpx = px - bx; bpy = py - by;\n\t\t\t\t\tcpx = px - cx; cpy = py - cy;\n\n\t\t\t\t\t// see if p is inside triangle abc\n\n\t\t\t\t\taCROSSbp = aX * bpy - aY * bpx;\n\t\t\t\t\tcCROSSap = cX * apy - cY * apx;\n\t\t\t\t\tbCROSScp = bX * cpy - bY * cpx;\n\n\t\t\t\t\tif ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;\n\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\t// takes in an contour array and returns\n\n\t\t\treturn function triangulate( contour, indices ) {\n\n\t\t\t\tvar n = contour.length;\n\n\t\t\t\tif ( n < 3 ) return null;\n\n\t\t\t\tvar result = [],\n\t\t\t\t\tverts = [],\n\t\t\t\t\tvertIndices = [];\n\n\t\t\t\t/* we want a counter-clockwise polygon in verts */\n\n\t\t\t\tvar u, v, w;\n\n\t\t\t\tif ( ShapeUtils.area( contour ) > 0.0 ) {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = v;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;\n\n\t\t\t\t}\n\n\t\t\t\tvar nv = n;\n\n\t\t\t\t/* remove nv - 2 vertices, creating 1 triangle every time */\n\n\t\t\t\tvar count = 2 * nv; /* error detection */\n\n\t\t\t\tfor ( v = nv - 1; nv > 2; ) {\n\n\t\t\t\t\t/* if we loop, it is probably a non-simple polygon */\n\n\t\t\t\t\tif ( ( count -- ) <= 0 ) {\n\n\t\t\t\t\t\t//** Triangulate: ERROR - probable bad polygon!\n\n\t\t\t\t\t\t//throw ( \"Warning, unable to triangulate polygon!\" );\n\t\t\t\t\t\t//return null;\n\t\t\t\t\t\t// Sometimes warning is fine, especially polygons are triangulated in reverse.\n\t\t\t\t\t\tconsole.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );\n\n\t\t\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t/* three consecutive vertices in current polygon, */\n\n\t\t\t\t\tu = v; \t \tif ( nv <= u ) u = 0; /* previous */\n\t\t\t\t\tv = u + 1; if ( nv <= v ) v = 0; /* new v */\n\t\t\t\t\tw = v + 1; if ( nv <= w ) w = 0; /* next */\n\n\t\t\t\t\tif ( snip( contour, u, v, w, nv, verts ) ) {\n\n\t\t\t\t\t\tvar a, b, c, s, t;\n\n\t\t\t\t\t\t/* true names of the vertices */\n\n\t\t\t\t\t\ta = verts[ u ];\n\t\t\t\t\t\tb = verts[ v ];\n\t\t\t\t\t\tc = verts[ w ];\n\n\t\t\t\t\t\t/* output Triangle */\n\n\t\t\t\t\t\tresult.push( [ contour[ a ],\n\t\t\t\t\t\t\tcontour[ b ],\n\t\t\t\t\t\t\tcontour[ c ] ] );\n\n\n\t\t\t\t\t\tvertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );\n\n\t\t\t\t\t\t/* remove v from the remaining polygon */\n\n\t\t\t\t\t\tfor ( s = v, t = v + 1; t < nv; s ++, t ++ ) {\n\n\t\t\t\t\t\t\tverts[ s ] = verts[ t ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnv --;\n\n\t\t\t\t\t\t/* reset error detection counter */\n\n\t\t\t\t\t\tcount = 2 * nv;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( indices ) return vertIndices;\n\t\t\t\treturn result;\n\n\t\t\t}\n\n\t\t} )(),\n\n\t\ttriangulateShape: function ( contour, holes ) {\n\n\t\t\tfunction removeDupEndPts(points) {\n\n\t\t\t\tvar l = points.length;\n\n\t\t\t\tif ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\t\tpoints.pop();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tremoveDupEndPts( contour );\n\t\t\tholes.forEach( removeDupEndPts );\n\n\t\t\tfunction point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {\n\n\t\t\t\t// inOtherPt needs to be collinear to the inSegment\n\t\t\t\tif ( inSegPt1.x !== inSegPt2.x ) {\n\n\t\t\t\t\tif ( inSegPt1.x < inSegPt2.x ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( inSegPt1.y < inSegPt2.y ) {\n\n\t\t\t\t\t\treturn\t( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\treturn\t( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {\n\n\t\t\t\tvar seg1dx = inSeg1Pt2.x - inSeg1Pt1.x, seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;\n\t\t\t\tvar seg2dx = inSeg2Pt2.x - inSeg2Pt1.x, seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;\n\n\t\t\t\tvar seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;\n\t\t\t\tvar seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;\n\n\t\t\t\tvar limit\t\t= seg1dy * seg2dx - seg1dx * seg2dy;\n\t\t\t\tvar perpSeg1\t= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;\n\n\t\t\t\tif ( Math.abs( limit ) > Number.EPSILON ) {\n\n\t\t\t\t\t// not parallel\n\n\t\t\t\t\tvar perpSeg2;\n\t\t\t\t\tif ( limit > 0 ) {\n\n\t\t\t\t\t\tif ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) \t\treturn [];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) \t\treturn [];\n\t\t\t\t\t\tperpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;\n\t\t\t\t\t\tif ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) \t\treturn [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// i.e. to reduce rounding errors\n\t\t\t\t\t// intersection at endpoint of segment#1?\n\t\t\t\t\tif ( perpSeg2 === 0 ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( perpSeg2 === limit ) {\n\n\t\t\t\t\t\tif ( ( inExcludeAdjacentSegs ) &&\n\t\t\t\t\t\t\t ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )\t\treturn [];\n\t\t\t\t\t\treturn [ inSeg1Pt2 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// intersection at endpoint of segment#2?\n\t\t\t\t\tif ( perpSeg1 === 0 )\t\treturn [ inSeg2Pt1 ];\n\t\t\t\t\tif ( perpSeg1 === limit )\treturn [ inSeg2Pt2 ];\n\n\t\t\t\t\t// return real intersection point\n\t\t\t\t\tvar factorSeg1 = perpSeg2 / limit;\n\t\t\t\t\treturn\t[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,\n\t\t\t\t\t\t\t\ty: inSeg1Pt1.y + factorSeg1 * seg1dy } ];\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// parallel or collinear\n\t\t\t\t\tif ( ( perpSeg1 !== 0 ) ||\n\t\t\t\t\t\t ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) \t\t\treturn [];\n\n\t\t\t\t\t// they are collinear or degenerate\n\t\t\t\t\tvar seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );\t// segment1 is just a point?\n\t\t\t\t\tvar seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );\t// segment2 is just a point?\n\t\t\t\t\t// both segments are points\n\t\t\t\t\tif ( seg1Pt && seg2Pt ) {\n\n\t\t\t\t\t\tif ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||\n\t\t\t\t\t\t\t ( inSeg1Pt1.y !== inSeg2Pt1.y ) )\t\treturn [];\t// they are distinct points\n\t\t\t\t\t\treturn [ inSeg1Pt1 ]; \t\t\t\t\t\t// they are the same point\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#1 is a single point\n\t\t\t\t\tif ( seg1Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )\t\treturn [];\t\t// but not in segment#2\n\t\t\t\t\t\treturn [ inSeg1Pt1 ];\n\n\t\t\t\t\t}\n\t\t\t\t\t// segment#2 is a single point\n\t\t\t\t\tif ( seg2Pt ) {\n\n\t\t\t\t\t\tif ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )\t\treturn [];\t\t// but not in segment#1\n\t\t\t\t\t\treturn [ inSeg2Pt1 ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// they are collinear segments, which might overlap\n\t\t\t\t\tvar seg1min, seg1max, seg1minVal, seg1maxVal;\n\t\t\t\t\tvar seg2min, seg2max, seg2minVal, seg2maxVal;\n\t\t\t\t\tif ( seg1dx !== 0 ) {\n\n\t\t\t\t\t\t// the segments are NOT on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.x < inSeg1Pt2.x ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.x < inSeg2Pt2.x ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// the segments are on a vertical line\n\t\t\t\t\t\tif ( inSeg1Pt1.y < inSeg1Pt2.y ) {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;\n\t\t\t\t\t\t\tseg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( inSeg2Pt1.y < inSeg2Pt2.y ) {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tseg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;\n\t\t\t\t\t\t\tseg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tif ( seg1minVal <= seg2minVal ) {\n\n\t\t\t\t\t\tif ( seg1maxVal < seg2minVal )\treturn [];\n\t\t\t\t\t\tif ( seg1maxVal === seg2minVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg2min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg2min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg2min, seg2max ];\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( seg1minVal > seg2maxVal )\treturn [];\n\t\t\t\t\t\tif ( seg1minVal === seg2maxVal )\t{\n\n\t\t\t\t\t\t\tif ( inExcludeAdjacentSegs )\t\treturn [];\n\t\t\t\t\t\t\treturn [ seg1min ];\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( seg1maxVal <= seg2maxVal )\treturn [ seg1min, seg1max ];\n\t\t\t\t\t\treturn\t[ seg1min, seg2max ];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {\n\n\t\t\t\t// The order of legs is important\n\n\t\t\t\t// translation of all points, so that Vertex is at (0,0)\n\t\t\t\tvar legFromPtX\t= inLegFromPt.x - inVertex.x, legFromPtY\t= inLegFromPt.y - inVertex.y;\n\t\t\t\tvar legToPtX\t= inLegToPt.x\t- inVertex.x, legToPtY\t\t= inLegToPt.y\t- inVertex.y;\n\t\t\t\tvar otherPtX\t= inOtherPt.x\t- inVertex.x, otherPtY\t\t= inOtherPt.y\t- inVertex.y;\n\n\t\t\t\t// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.\n\t\t\t\tvar from2toAngle\t= legFromPtX * legToPtY - legFromPtY * legToPtX;\n\t\t\t\tvar from2otherAngle\t= legFromPtX * otherPtY - legFromPtY * otherPtX;\n\n\t\t\t\tif ( Math.abs( from2toAngle ) > Number.EPSILON ) {\n\n\t\t\t\t\t// angle != 180 deg.\n\n\t\t\t\t\tvar other2toAngle\t\t= otherPtX * legToPtY - otherPtY * legToPtX;\n\t\t\t\t\t// console.log( \"from2to: \" + from2toAngle + \", from2other: \" + from2otherAngle + \", other2to: \" + other2toAngle );\n\n\t\t\t\t\tif ( from2toAngle > 0 ) {\n\n\t\t\t\t\t\t// main angle < 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// main angle > 180 deg.\n\t\t\t\t\t\treturn\t( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// angle == 180 deg.\n\t\t\t\t\t// console.log( \"from2to: 180 deg., from2other: \" + from2otherAngle );\n\t\t\t\t\treturn\t( from2otherAngle > 0 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\n\t\t\tfunction removeHoles( contour, holes ) {\n\n\t\t\t\tvar shape = contour.concat(); // work on this shape\n\t\t\t\tvar hole;\n\n\t\t\t\tfunction isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {\n\n\t\t\t\t\t// Check if hole point lies within angle around shape point\n\t\t\t\t\tvar lastShapeIdx = shape.length - 1;\n\n\t\t\t\t\tvar prevShapeIdx = inShapeIdx - 1;\n\t\t\t\t\tif ( prevShapeIdx < 0 )\t\t\tprevShapeIdx = lastShapeIdx;\n\n\t\t\t\t\tvar nextShapeIdx = inShapeIdx + 1;\n\t\t\t\t\tif ( nextShapeIdx > lastShapeIdx )\tnextShapeIdx = 0;\n\n\t\t\t\t\tvar insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Shape): \" + inShapeIdx + \", Point: \" + hole[inHoleIdx].x + \"/\" + hole[inHoleIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if shape point lies within angle around hole point\n\t\t\t\t\tvar lastHoleIdx = hole.length - 1;\n\n\t\t\t\t\tvar prevHoleIdx = inHoleIdx - 1;\n\t\t\t\t\tif ( prevHoleIdx < 0 )\t\t\tprevHoleIdx = lastHoleIdx;\n\n\t\t\t\t\tvar nextHoleIdx = inHoleIdx + 1;\n\t\t\t\t\tif ( nextHoleIdx > lastHoleIdx )\tnextHoleIdx = 0;\n\n\t\t\t\t\tinsideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );\n\t\t\t\t\tif ( ! insideAngle ) {\n\n\t\t\t\t\t\t// console.log( \"Vertex (Hole): \" + inHoleIdx + \", Point: \" + shape[inShapeIdx].x + \"/\" + shape[inShapeIdx].y );\n\t\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\ttrue;\n\n\t\t\t\t}\n\n\t\t\t\tfunction intersectsShapeEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with shape edges\n\t\t\t\t\tvar sIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {\n\n\t\t\t\t\t\tnextIdx = sIdx + 1; nextIdx %= shape.length;\n\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );\n\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar indepHoles = [];\n\n\t\t\t\tfunction intersectsHoleEdge( inShapePt, inHolePt ) {\n\n\t\t\t\t\t// checks for intersections with hole edges\n\t\t\t\t\tvar ihIdx, chkHole,\n\t\t\t\t\t\thIdx, nextIdx, intersection;\n\t\t\t\t\tfor ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {\n\n\t\t\t\t\t\tchkHole = holes[ indepHoles[ ihIdx ]];\n\t\t\t\t\t\tfor ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {\n\n\t\t\t\t\t\t\tnextIdx = hIdx + 1; nextIdx %= chkHole.length;\n\t\t\t\t\t\t\tintersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );\n\t\t\t\t\t\t\tif ( intersection.length > 0 )\t\treturn\ttrue;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn\tfalse;\n\n\t\t\t\t}\n\n\t\t\t\tvar holeIndex, shapeIndex,\n\t\t\t\t\tshapePt, holePt,\n\t\t\t\t\tholeIdx, cutKey, failedCuts = [],\n\t\t\t\t\ttmpShape1, tmpShape2,\n\t\t\t\t\ttmpHole1, tmpHole2;\n\n\t\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\t\tindepHoles.push( h );\n\n\t\t\t\t}\n\n\t\t\t\tvar minShapeIndex = 0;\n\t\t\t\tvar counter = indepHoles.length * 2;\n\t\t\t\twhile ( indepHoles.length > 0 ) {\n\n\t\t\t\t\tcounter --;\n\t\t\t\t\tif ( counter < 0 ) {\n\n\t\t\t\t\t\tconsole.log( \"Infinite Loop! Holes left:\" + indepHoles.length + \", Probably Hole outside Shape!\" );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// search for shape-vertex and hole-vertex,\n\t\t\t\t\t// which can be connected without intersections\n\t\t\t\t\tfor ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {\n\n\t\t\t\t\t\tshapePt = shape[ shapeIndex ];\n\t\t\t\t\t\tholeIndex\t= - 1;\n\n\t\t\t\t\t\t// search for hole which can be reached without intersections\n\t\t\t\t\t\tfor ( var h = 0; h < indepHoles.length; h ++ ) {\n\n\t\t\t\t\t\t\tholeIdx = indepHoles[ h ];\n\n\t\t\t\t\t\t\t// prevent multiple checks\n\t\t\t\t\t\t\tcutKey = shapePt.x + \":\" + shapePt.y + \":\" + holeIdx;\n\t\t\t\t\t\t\tif ( failedCuts[ cutKey ] !== undefined )\t\t\tcontinue;\n\n\t\t\t\t\t\t\thole = holes[ holeIdx ];\n\t\t\t\t\t\t\tfor ( var h2 = 0; h2 < hole.length; h2 ++ ) {\n\n\t\t\t\t\t\t\t\tholePt = hole[ h2 ];\n\t\t\t\t\t\t\t\tif ( ! isCutLineInsideAngles( shapeIndex, h2 ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsShapeEdge( shapePt, holePt ) )\t\tcontinue;\n\t\t\t\t\t\t\t\tif ( intersectsHoleEdge( shapePt, holePt ) )\t\tcontinue;\n\n\t\t\t\t\t\t\t\tholeIndex = h2;\n\t\t\t\t\t\t\t\tindepHoles.splice( h, 1 );\n\n\t\t\t\t\t\t\t\ttmpShape1 = shape.slice( 0, shapeIndex + 1 );\n\t\t\t\t\t\t\t\ttmpShape2 = shape.slice( shapeIndex );\n\t\t\t\t\t\t\t\ttmpHole1 = hole.slice( holeIndex );\n\t\t\t\t\t\t\t\ttmpHole2 = hole.slice( 0, holeIndex + 1 );\n\n\t\t\t\t\t\t\t\tshape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );\n\n\t\t\t\t\t\t\t\tminShapeIndex = shapeIndex;\n\n\t\t\t\t\t\t\t\t// Debug only, to show the selected cuts\n\t\t\t\t\t\t\t\t// glob_CutLines.push( [ shapePt, holePt ] );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t\t\tfailedCuts[ cutKey ] = true;\t\t\t// remember failure\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( holeIndex >= 0 )\tbreak;\t\t// hole-vertex found\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn shape; \t\t\t/* shape with no holes */\n\n\t\t\t}\n\n\n\t\t\tvar i, il, f, face,\n\t\t\t\tkey, index,\n\t\t\t\tallPointsMap = {};\n\n\t\t\t// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.\n\n\t\t\tvar allpoints = contour.concat();\n\n\t\t\tfor ( var h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( allpoints, holes[ h ] );\n\n\t\t\t}\n\n\t\t\t//console.log( \"allpoints\",allpoints, allpoints.length );\n\n\t\t\t// prepare all points map\n\n\t\t\tfor ( i = 0, il = allpoints.length; i < il; i ++ ) {\n\n\t\t\t\tkey = allpoints[ i ].x + \":\" + allpoints[ i ].y;\n\n\t\t\t\tif ( allPointsMap[ key ] !== undefined ) {\n\n\t\t\t\t\tconsole.warn( \"THREE.ShapeUtils: Duplicate point\", key, i );\n\n\t\t\t\t}\n\n\t\t\t\tallPointsMap[ key ] = i;\n\n\t\t\t}\n\n\t\t\t// remove holes by cutting paths to holes and adding them to the shape\n\t\t\tvar shapeWithoutHoles = removeHoles( contour, holes );\n\n\t\t\tvar triangles = ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape\n\t\t\t//console.log( \"triangles\",triangles, triangles.length );\n\n\t\t\t// check all face vertices against all points map\n\n\t\t\tfor ( i = 0, il = triangles.length; i < il; i ++ ) {\n\n\t\t\t\tface = triangles[ i ];\n\n\t\t\t\tfor ( f = 0; f < 3; f ++ ) {\n\n\t\t\t\t\tkey = face[ f ].x + \":\" + face[ f ].y;\n\n\t\t\t\t\tindex = allPointsMap[ key ];\n\n\t\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\t\tface[ f ] = index;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn triangles.concat();\n\n\t\t},\n\n\t\tisClockWise: function ( pts ) {\n\n\t\t\treturn ShapeUtils.area( pts ) < 0;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Creates extruded geometry from a path shape.\n\t *\n\t * parameters = {\n\t *\n\t * curveSegments: , // number of points on the curves\n\t * steps: , // number of points for z-side extrusions / used for subdividing segments of extrude spline too\n\t * amount: , // Depth to extrude the shape\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into the original shape bevel goes\n\t * bevelSize: , // how far from shape outline is bevel\n\t * bevelSegments: , // number of bevel layers\n\t *\n\t * extrudePath: // curve to extrude shape along\n\t * frames: // containing arrays of tangents, normals, binormals\n\t *\n\t * uvGenerator: // object that provides UV generator functions\n\t *\n\t * }\n\t **/\n\n\tfunction ExtrudeGeometry( shapes, options ) {\n\n\t\tif ( typeof( shapes ) === \"undefined\" ) {\n\n\t\t\tshapes = [];\n\t\t\treturn;\n\n\t\t}\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ExtrudeGeometry';\n\n\t\tshapes = Array.isArray( shapes ) ? shapes : [ shapes ];\n\n\t\tthis.addShapeList( shapes, options );\n\n\t\tthis.computeFaceNormals();\n\n\t\t// can't really use automatic vertex normals\n\t\t// as then front and back sides get smoothed too\n\t\t// should do separate smoothing just for sides\n\n\t\t//this.computeVertexNormals();\n\n\t\t//console.log( \"took\", ( Date.now() - startTime ) );\n\n\t}\n\n\tExtrudeGeometry.prototype = Object.create( Geometry.prototype );\n\tExtrudeGeometry.prototype.constructor = ExtrudeGeometry;\n\n\tExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {\n\n\t\tvar sl = shapes.length;\n\n\t\tfor ( var s = 0; s < sl; s ++ ) {\n\n\t\t\tvar shape = shapes[ s ];\n\t\t\tthis.addShape( shape, options );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.prototype.addShape = function ( shape, options ) {\n\n\t\tvar amount = options.amount !== undefined ? options.amount : 100;\n\n\t\tvar bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10\n\t\tvar bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8\n\t\tvar bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;\n\n\t\tvar bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false\n\n\t\tvar curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;\n\n\t\tvar steps = options.steps !== undefined ? options.steps : 1;\n\n\t\tvar extrudePath = options.extrudePath;\n\t\tvar extrudePts, extrudeByPath = false;\n\n\t\t// Use default WorldUVGenerator if no UV generators are specified.\n\t\tvar uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;\n\n\t\tvar splineTube, binormal, normal, position2;\n\t\tif ( extrudePath ) {\n\n\t\t\textrudePts = extrudePath.getSpacedPoints( steps );\n\n\t\t\textrudeByPath = true;\n\t\t\tbevelEnabled = false; // bevels not supported for path extrusion\n\n\t\t\t// SETUP TNB variables\n\n\t\t\t// TODO1 - have a .isClosed in spline?\n\n\t\t\tsplineTube = options.frames !== undefined ? options.frames : extrudePath.computeFrenetFrames( steps, false );\n\n\t\t\t// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);\n\n\t\t\tbinormal = new Vector3();\n\t\t\tnormal = new Vector3();\n\t\t\tposition2 = new Vector3();\n\n\t\t}\n\n\t\t// Safeguards if bevels are not enabled\n\n\t\tif ( ! bevelEnabled ) {\n\n\t\t\tbevelSegments = 0;\n\t\t\tbevelThickness = 0;\n\t\t\tbevelSize = 0;\n\n\t\t}\n\n\t\t// Variables initialization\n\n\t\tvar ahole, h, hl; // looping of holes\n\t\tvar scope = this;\n\n\t\tvar shapesOffset = this.vertices.length;\n\n\t\tvar shapePoints = shape.extractPoints( curveSegments );\n\n\t\tvar vertices = shapePoints.shape;\n\t\tvar holes = shapePoints.holes;\n\n\t\tvar reverse = ! ShapeUtils.isClockWise( vertices );\n\n\t\tif ( reverse ) {\n\n\t\t\tvertices = vertices.reverse();\n\n\t\t\t// Maybe we should also check if holes are in the opposite direction, just to be safe ...\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\n\t\t\t\tif ( ShapeUtils.isClockWise( ahole ) ) {\n\n\t\t\t\t\tholes[ h ] = ahole.reverse();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!\n\n\t\t}\n\n\n\t\tvar faces = ShapeUtils.triangulateShape( vertices, holes );\n\n\t\t/* Vertices */\n\n\t\tvar contour = vertices; // vertices has all points but contour has only points of circumference\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\tvertices = vertices.concat( ahole );\n\n\t\t}\n\n\n\t\tfunction scalePt2( pt, vec, size ) {\n\n\t\t\tif ( ! vec ) console.error( \"THREE.ExtrudeGeometry: vec does not exist\" );\n\n\t\t\treturn vec.clone().multiplyScalar( size ).add( pt );\n\n\t\t}\n\n\t\tvar b, bs, t, z,\n\t\t\tvert, vlen = vertices.length,\n\t\t\tface, flen = faces.length;\n\n\n\t\t// Find directions for point movement\n\n\n\t\tfunction getBevelVec( inPt, inPrev, inNext ) {\n\n\t\t\t// computes for inPt the corresponding point inPt' on a new contour\n\t\t\t// shifted by 1 unit (length of normalized vector) to the left\n\t\t\t// if we walk along contour clockwise, this new contour is outside the old one\n\t\t\t//\n\t\t\t// inPt' is the intersection of the two lines parallel to the two\n\t\t\t// adjacent edges of inPt at a distance of 1 unit on the left side.\n\n\t\t\tvar v_trans_x, v_trans_y, shrink_by = 1;\t\t// resulting translation vector for inPt\n\n\t\t\t// good reading for geometry algorithms (here: line-line intersection)\n\t\t\t// http://geomalgorithms.com/a05-_intersect-1.html\n\n\t\t\tvar v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y;\n\t\t\tvar v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y;\n\n\t\t\tvar v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );\n\n\t\t\t// check for collinear edges\n\t\t\tvar collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\tif ( Math.abs( collinear0 ) > Number.EPSILON ) {\n\n\t\t\t\t// not collinear\n\n\t\t\t\t// length of vectors for normalizing\n\n\t\t\t\tvar v_prev_len = Math.sqrt( v_prev_lensq );\n\t\t\t\tvar v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );\n\n\t\t\t\t// shift adjacent points by unit vectors to the left\n\n\t\t\t\tvar ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );\n\t\t\t\tvar ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );\n\n\t\t\t\tvar ptNextShift_x = ( inNext.x - v_next_y / v_next_len );\n\t\t\t\tvar ptNextShift_y = ( inNext.y + v_next_x / v_next_len );\n\n\t\t\t\t// scaling factor for v_prev to intersection point\n\n\t\t\t\tvar sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -\n\t\t\t\t\t\t\t( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /\n\t\t\t\t\t\t ( v_prev_x * v_next_y - v_prev_y * v_next_x );\n\n\t\t\t\t// vector from inPt to intersection point\n\n\t\t\t\tv_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );\n\t\t\t\tv_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );\n\n\t\t\t\t// Don't normalize!, otherwise sharp corners become ugly\n\t\t\t\t// but prevent crazy spikes\n\t\t\t\tvar v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );\n\t\t\t\tif ( v_trans_lensq <= 2 ) {\n\n\t\t\t\t\treturn\tnew Vector2( v_trans_x, v_trans_y );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tshrink_by = Math.sqrt( v_trans_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// handle special case of collinear edges\n\n\t\t\t\tvar direction_eq = false;\t\t// assumes: opposite\n\t\t\t\tif ( v_prev_x > Number.EPSILON ) {\n\n\t\t\t\t\tif ( v_next_x > Number.EPSILON ) {\n\n\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( v_prev_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\tif ( v_next_x < - Number.EPSILON ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {\n\n\t\t\t\t\t\t\tdirection_eq = true;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction_eq ) {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight sequence\");\n\t\t\t\t\tv_trans_x = - v_prev_y;\n\t\t\t\t\tv_trans_y = v_prev_x;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// console.log(\"Warning: lines are a straight spike\");\n\t\t\t\t\tv_trans_x = v_prev_x;\n\t\t\t\t\tv_trans_y = v_prev_y;\n\t\t\t\t\tshrink_by = Math.sqrt( v_prev_lensq / 2 );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn\tnew Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );\n\n\t\t}\n\n\n\t\tvar contourMovements = [];\n\n\t\tfor ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\tif ( j === il ) j = 0;\n\t\t\tif ( k === il ) k = 0;\n\n\t\t\t// (j)---(i)---(k)\n\t\t\t// console.log('i,j,k', i, j , k)\n\n\t\t\tcontourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );\n\n\t\t}\n\n\t\tvar holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();\n\n\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\tahole = holes[ h ];\n\n\t\t\toneHoleMovements = [];\n\n\t\t\tfor ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {\n\n\t\t\t\tif ( j === il ) j = 0;\n\t\t\t\tif ( k === il ) k = 0;\n\n\t\t\t\t// (j)---(i)---(k)\n\t\t\t\toneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );\n\n\t\t\t}\n\n\t\t\tholesMovements.push( oneHoleMovements );\n\t\t\tverticesMovements = verticesMovements.concat( oneHoleMovements );\n\n\t\t}\n\n\n\t\t// Loop bevelSegments, 1 for the front, 1 for the back\n\n\t\tfor ( b = 0; b < bevelSegments; b ++ ) {\n\n\t\t\t//for ( b = bevelSegments; b > 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\n\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tv( vert.x, vert.y, - z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tbs = bevelSize;\n\n\t\t// Back facing vertices\n\n\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\tv( vert.x, vert.y, 0 );\n\n\t\t\t} else {\n\n\t\t\t\t// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );\n\n\t\t\t\tnormal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );\n\t\t\t\tbinormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );\n\n\t\t\t\tposition2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );\n\n\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Add stepped vertices...\n\t\t// Including front facing vertices\n\n\t\tvar s;\n\n\t\tfor ( s = 1; s <= steps; s ++ ) {\n\n\t\t\tfor ( i = 0; i < vlen; i ++ ) {\n\n\t\t\t\tvert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];\n\n\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\tv( vert.x, vert.y, amount / steps * s );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );\n\n\t\t\t\t\tnormal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );\n\t\t\t\t\tbinormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );\n\n\t\t\t\t\tposition2.copy( extrudePts[ s ] ).add( normal ).add( binormal );\n\n\t\t\t\t\tv( position2.x, position2.y, position2.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\t// Add bevel segments planes\n\n\t\t//for ( b = 1; b <= bevelSegments; b ++ ) {\n\t\tfor ( b = bevelSegments - 1; b >= 0; b -- ) {\n\n\t\t\tt = b / bevelSegments;\n\t\t\tz = bevelThickness * Math.cos ( t * Math.PI / 2 );\n\t\t\tbs = bevelSize * Math.sin( t * Math.PI / 2 );\n\n\t\t\t// contract shape\n\n\t\t\tfor ( i = 0, il = contour.length; i < il; i ++ ) {\n\n\t\t\t\tvert = scalePt2( contour[ i ], contourMovements[ i ], bs );\n\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t}\n\n\t\t\t// expand holes\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\toneHoleMovements = holesMovements[ h ];\n\n\t\t\t\tfor ( i = 0, il = ahole.length; i < il; i ++ ) {\n\n\t\t\t\t\tvert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );\n\n\t\t\t\t\tif ( ! extrudeByPath ) {\n\n\t\t\t\t\t\tv( vert.x, vert.y, amount + z );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tv( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t/* Faces */\n\n\t\t// Top and bottom faces\n\n\t\tbuildLidFaces();\n\n\t\t// Sides faces\n\n\t\tbuildSideFaces();\n\n\n\t\t///// Internal functions\n\n\t\tfunction buildLidFaces() {\n\n\t\t\tif ( bevelEnabled ) {\n\n\t\t\t\tvar layer = 0; // steps + 1\n\t\t\t\tvar offset = vlen * layer;\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t\tlayer = steps + bevelSegments * 2;\n\t\t\t\toffset = vlen * layer;\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Bottom faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 2 ], face[ 1 ], face[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\t// Top faces\n\n\t\t\t\tfor ( i = 0; i < flen; i ++ ) {\n\n\t\t\t\t\tface = faces[ i ];\n\t\t\t\t\tf3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Create faces for the z-sides of the shape\n\n\t\tfunction buildSideFaces() {\n\n\t\t\tvar layeroffset = 0;\n\t\t\tsidewalls( contour, layeroffset );\n\t\t\tlayeroffset += contour.length;\n\n\t\t\tfor ( h = 0, hl = holes.length; h < hl; h ++ ) {\n\n\t\t\t\tahole = holes[ h ];\n\t\t\t\tsidewalls( ahole, layeroffset );\n\n\t\t\t\t//, true\n\t\t\t\tlayeroffset += ahole.length;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction sidewalls( contour, layeroffset ) {\n\n\t\t\tvar j, k;\n\t\t\ti = contour.length;\n\n\t\t\twhile ( -- i >= 0 ) {\n\n\t\t\t\tj = i;\n\t\t\t\tk = i - 1;\n\t\t\t\tif ( k < 0 ) k = contour.length - 1;\n\n\t\t\t\t//console.log('b', i,j, i-1, k,vertices.length);\n\n\t\t\t\tvar s = 0, sl = steps + bevelSegments * 2;\n\n\t\t\t\tfor ( s = 0; s < sl; s ++ ) {\n\n\t\t\t\t\tvar slen1 = vlen * s;\n\t\t\t\t\tvar slen2 = vlen * ( s + 1 );\n\n\t\t\t\t\tvar a = layeroffset + j + slen1,\n\t\t\t\t\t\tb = layeroffset + k + slen1,\n\t\t\t\t\t\tc = layeroffset + k + slen2,\n\t\t\t\t\t\td = layeroffset + j + slen2;\n\n\t\t\t\t\tf4( a, b, c, d, contour, s, sl, j, k );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\n\t\tfunction v( x, y, z ) {\n\n\t\t\tscope.vertices.push( new Vector3( x, y, z ) );\n\n\t\t}\n\n\t\tfunction f3( a, b, c ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, c, null, null, 0 ) );\n\n\t\t\tvar uvs = uvgen.generateTopUV( scope, a, b, c );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( uvs );\n\n\t\t}\n\n\t\tfunction f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {\n\n\t\t\ta += shapesOffset;\n\t\t\tb += shapesOffset;\n\t\t\tc += shapesOffset;\n\t\t\td += shapesOffset;\n\n\t\t\tscope.faces.push( new Face3( a, b, d, null, null, 1 ) );\n\t\t\tscope.faces.push( new Face3( b, c, d, null, null, 1 ) );\n\n\t\t\tvar uvs = uvgen.generateSideWallUV( scope, a, b, c, d );\n\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ] );\n\t\t\tscope.faceVertexUvs[ 0 ].push( [ uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ] );\n\n\t\t}\n\n\t};\n\n\tExtrudeGeometry.WorldUVGenerator = {\n\n\t\tgenerateTopUV: function ( geometry, indexA, indexB, indexC ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\n\t\t\treturn [\n\t\t\t\tnew Vector2( a.x, a.y ),\n\t\t\t\tnew Vector2( b.x, b.y ),\n\t\t\t\tnew Vector2( c.x, c.y )\n\t\t\t];\n\n\t\t},\n\n\t\tgenerateSideWallUV: function ( geometry, indexA, indexB, indexC, indexD ) {\n\n\t\t\tvar vertices = geometry.vertices;\n\n\t\t\tvar a = vertices[ indexA ];\n\t\t\tvar b = vertices[ indexB ];\n\t\t\tvar c = vertices[ indexC ];\n\t\t\tvar d = vertices[ indexD ];\n\n\t\t\tif ( Math.abs( a.y - b.y ) < 0.01 ) {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.x, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.x, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.x, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.x, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t} else {\n\n\t\t\t\treturn [\n\t\t\t\t\tnew Vector2( a.y, 1 - a.z ),\n\t\t\t\t\tnew Vector2( b.y, 1 - b.z ),\n\t\t\t\t\tnew Vector2( c.y, 1 - c.z ),\n\t\t\t\t\tnew Vector2( d.y, 1 - d.z )\n\t\t\t\t];\n\n\t\t\t}\n\n\t\t}\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Text = 3D Text\n\t *\n\t * parameters = {\n\t * font: , // font\n\t *\n\t * size: , // size of the text\n\t * height: , // thickness to extrude text\n\t * curveSegments: , // number of points on the curves\n\t *\n\t * bevelEnabled: , // turn on bevel\n\t * bevelThickness: , // how deep into text bevel goes\n\t * bevelSize: // how far from text outline is bevel\n\t * }\n\t */\n\n\tfunction TextGeometry( text, parameters ) {\n\n\t\tparameters = parameters || {};\n\n\t\tvar font = parameters.font;\n\n\t\tif ( ( font && font.isFont ) === false ) {\n\n\t\t\tconsole.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );\n\t\t\treturn new Geometry();\n\n\t\t}\n\n\t\tvar shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );\n\n\t\t// translate parameters to ExtrudeGeometry API\n\n\t\tparameters.amount = parameters.height !== undefined ? parameters.height : 50;\n\n\t\t// defaults\n\n\t\tif ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;\n\t\tif ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;\n\t\tif ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;\n\n\t\tExtrudeGeometry.call( this, shapes, parameters );\n\n\t\tthis.type = 'TextGeometry';\n\n\t}\n\n\tTextGeometry.prototype = Object.create( ExtrudeGeometry.prototype );\n\tTextGeometry.prototype.constructor = TextGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'SphereGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );\n\n\t}\n\n\tSphereGeometry.prototype = Object.create( Geometry.prototype );\n\tSphereGeometry.prototype.constructor = SphereGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'SphereBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\n\t\twidthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );\n\t\theightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );\n\n\t\tphiStart = phiStart !== undefined ? phiStart : 0;\n\t\tphiLength = phiLength !== undefined ? phiLength : Math.PI * 2;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI;\n\n\t\tvar thetaEnd = thetaStart + thetaLength;\n\n\t\tvar ix, iy;\n\n\t\tvar index = 0;\n\t\tvar grid = [];\n\n\t\tvar vertex = new Vector3();\n\t\tvar normal = new Vector3();\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( iy = 0; iy <= heightSegments; iy ++ ) {\n\n\t\t\tvar verticesRow = [];\n\n\t\t\tvar v = iy / heightSegments;\n\n\t\t\tfor ( ix = 0; ix <= widthSegments; ix ++ ) {\n\n\t\t\t\tvar u = ix / widthSegments;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\t\t\t\tvertex.y = radius * Math.cos( thetaStart + v * thetaLength );\n\t\t\t\tvertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormal.set( vertex.x, vertex.y, vertex.z ).normalize();\n\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\tverticesRow.push( index ++ );\n\n\t\t\t}\n\n\t\t\tgrid.push( verticesRow );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( iy = 0; iy < heightSegments; iy ++ ) {\n\n\t\t\tfor ( ix = 0; ix < widthSegments; ix ++ ) {\n\n\t\t\t\tvar a = grid[ iy ][ ix + 1 ];\n\t\t\t\tvar b = grid[ iy ][ ix ];\n\t\t\t\tvar c = grid[ iy + 1 ][ ix ];\n\t\t\t\tvar d = grid[ iy + 1 ][ ix + 1 ];\n\n\t\t\t\tif ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );\n\t\t\t\tif ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tSphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tSphereBufferGeometry.prototype.constructor = SphereBufferGeometry;\n\n\t/**\n\t * @author Kaleb Murphy\n\t */\n\n\tfunction RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'RingGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );\n\n\t}\n\n\tRingGeometry.prototype = Object.create( Geometry.prototype );\n\tRingGeometry.prototype.constructor = RingGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'RingBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tinnerRadius: innerRadius,\n\t\t\touterRadius: outerRadius,\n\t\t\tthetaSegments: thetaSegments,\n\t\t\tphiSegments: phiSegments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tinnerRadius = innerRadius || 20;\n\t\touterRadius = outerRadius || 50;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tthetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;\n\t\tphiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// some helper variables\n\n\t\tvar segment;\n\t\tvar radius = innerRadius;\n\t\tvar radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar j, i;\n\n\t\t// generate vertices, normals and uvs\n\n\t\tfor ( j = 0; j <= phiSegments; j ++ ) {\n\n\t\t\tfor ( i = 0; i <= thetaSegments; i ++ ) {\n\n\t\t\t\t// values are generate from the inside of the ring to the outside\n\n\t\t\t\tsegment = thetaStart + i / thetaSegments * thetaLength;\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( vertex.x / outerRadius + 1 ) / 2;\n\t\t\t\tuv.y = ( vertex.y / outerRadius + 1 ) / 2;\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t}\n\n\t\t\t// increase the radius for next row of vertices\n\n\t\t\tradius += radiusStep;\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( j = 0; j < phiSegments; j ++ ) {\n\n\t\t\tvar thetaSegmentLevel = j * ( thetaSegments + 1 );\n\n\t\t\tfor ( i = 0; i < thetaSegments; i ++ ) {\n\n\t\t\t\tsegment = i + thetaSegmentLevel;\n\n\t\t\t\tvar a = segment;\n\t\t\t\tvar b = segment + thetaSegments + 1;\n\t\t\t\tvar c = segment + thetaSegments + 2;\n\t\t\t\tvar d = segment + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tRingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tRingBufferGeometry.prototype.constructor = RingBufferGeometry;\n\n\t/**\n\t * @author astrodud / http://astrodud.isgreat.org/\n\t * @author zz85 / https://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t */\n\n\t// points - to create a closed torus, one must use a set of points\n\t// like so: [ a, b, c, d, a ], see first is the same as last.\n\t// segments - the number of circumference segments to create\n\t// phiStart - the starting radian\n\t// phiLength - the radian (0 to 2PI) range of the lathed section\n\t// 2PI is a closed lathe, less than 2PI is a portion.\n\n\tfunction LatheGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'LatheGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tLatheGeometry.prototype = Object.create( Geometry.prototype );\n\tLatheGeometry.prototype.constructor = LatheGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction LatheBufferGeometry( points, segments, phiStart, phiLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'LatheBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tpoints: points,\n\t\t\tsegments: segments,\n\t\t\tphiStart: phiStart,\n\t\t\tphiLength: phiLength\n\t\t};\n\n\t\tsegments = Math.floor( segments ) || 12;\n\t\tphiStart = phiStart || 0;\n\t\tphiLength = phiLength || Math.PI * 2;\n\n\t\t// clamp phiLength so it's in range of [ 0, 2PI ]\n\n\t\tphiLength = _Math.clamp( phiLength, 0, Math.PI * 2 );\n\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar base;\n\t\tvar inverseSegments = 1.0 / segments;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\t\tvar i, j;\n\n\t\t// generate vertices and uvs\n\n\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\tvar phi = phiStart + i * inverseSegments * phiLength;\n\n\t\t\tvar sin = Math.sin( phi );\n\t\t\tvar cos = Math.cos( phi );\n\n\t\t\tfor ( j = 0; j <= ( points.length - 1 ); j ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = points[ j ].x * sin;\n\t\t\t\tvertex.y = points[ j ].y;\n\t\t\t\tvertex.z = points[ j ].x * cos;\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = i / segments;\n\t\t\t\tuv.y = j / ( points.length - 1 );\n\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\n\t\t\t}\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 0; i < segments; i ++ ) {\n\n\t\t\tfor ( j = 0; j < ( points.length - 1 ); j ++ ) {\n\n\t\t\t\tbase = j + i * points.length;\n\n\t\t\t\tvar a = base;\n\t\t\t\tvar b = base + points.length;\n\t\t\t\tvar c = base + points.length + 1;\n\t\t\t\tvar d = base + 1;\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push( a, b, d );\n\t\t\t\tindices.push( b, c, d );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\t// generate normals\n\n\t\tthis.computeVertexNormals();\n\n\t\t// if the geometry is closed, we need to average the normals along the seam.\n\t\t// because the corresponding vertices are identical (but still have different UVs).\n\n\t\tif ( phiLength === Math.PI * 2 ) {\n\n\t\t\tvar normals = this.attributes.normal.array;\n\t\t\tvar n1 = new Vector3();\n\t\t\tvar n2 = new Vector3();\n\t\t\tvar n = new Vector3();\n\n\t\t\t// this is the buffer offset for the last line of vertices\n\n\t\t\tbase = segments * points.length * 3;\n\n\t\t\tfor ( i = 0, j = 0; i < points.length; i ++, j += 3 ) {\n\n\t\t\t\t// select the normal of the vertex in the first line\n\n\t\t\t\tn1.x = normals[ j + 0 ];\n\t\t\t\tn1.y = normals[ j + 1 ];\n\t\t\t\tn1.z = normals[ j + 2 ];\n\n\t\t\t\t// select the normal of the vertex in the last line\n\n\t\t\t\tn2.x = normals[ base + j + 0 ];\n\t\t\t\tn2.y = normals[ base + j + 1 ];\n\t\t\t\tn2.z = normals[ base + j + 2 ];\n\n\t\t\t\t// average normals\n\n\t\t\t\tn.addVectors( n1, n2 ).normalize();\n\n\t\t\t\t// assign the new values to both normals\n\n\t\t\t\tnormals[ j + 0 ] = normals[ base + j + 0 ] = n.x;\n\t\t\t\tnormals[ j + 1 ] = normals[ base + j + 1 ] = n.y;\n\t\t\t\tnormals[ j + 2 ] = normals[ base + j + 2 ] = n.z;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tLatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tLatheBufferGeometry.prototype.constructor = LatheBufferGeometry;\n\n\t/**\n\t * @author jonobr1 / http://jonobr1.com\n\t */\n\n\tfunction ShapeGeometry( shapes, curveSegments ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'ShapeGeometry';\n\n\t\tif ( typeof curveSegments === 'object' ) {\n\n\t\t\tconsole.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );\n\n\t\t\tcurveSegments = curveSegments.curveSegments;\n\n\t\t}\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tthis.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tShapeGeometry.prototype = Object.create( Geometry.prototype );\n\tShapeGeometry.prototype.constructor = ShapeGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction ShapeBufferGeometry( shapes, curveSegments ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'ShapeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tshapes: shapes,\n\t\t\tcurveSegments: curveSegments\n\t\t};\n\n\t\tcurveSegments = curveSegments || 12;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar groupStart = 0;\n\t\tvar groupCount = 0;\n\n\t\t// allow single and array values for \"shapes\" parameter\n\n\t\tif ( Array.isArray( shapes ) === false ) {\n\n\t\t\taddShape( shapes );\n\n\t\t} else {\n\n\t\t\tfor ( var i = 0; i < shapes.length; i ++ ) {\n\n\t\t\t\taddShape( shapes[ i ] );\n\n\t\t\t\tthis.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support\n\n\t\t\t\tgroupStart += groupCount;\n\t\t\t\tgroupCount = 0;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\n\t\t// helper functions\n\n\t\tfunction addShape( shape ) {\n\n\t\t\tvar i, l, shapeHole;\n\n\t\t\tvar indexOffset = vertices.length / 3;\n\t\t\tvar points = shape.extractPoints( curveSegments );\n\n\t\t\tvar shapeVertices = points.shape;\n\t\t\tvar shapeHoles = points.holes;\n\n\t\t\t// check direction of vertices\n\n\t\t\tif ( ShapeUtils.isClockWise( shapeVertices ) === false ) {\n\n\t\t\t\tshapeVertices = shapeVertices.reverse();\n\n\t\t\t\t// also check if holes are in the opposite direction\n\n\t\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\t\tshapeHole = shapeHoles[ i ];\n\n\t\t\t\t\tif ( ShapeUtils.isClockWise( shapeHole ) === true ) {\n\n\t\t\t\t\t\tshapeHoles[ i ] = shapeHole.reverse();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );\n\n\t\t\t// join vertices of inner and outer paths to a single array\n\n\t\t\tfor ( i = 0, l = shapeHoles.length; i < l; i ++ ) {\n\n\t\t\t\tshapeHole = shapeHoles[ i ];\n\t\t\t\tshapeVertices = shapeVertices.concat( shapeHole );\n\n\t\t\t}\n\n\t\t\t// vertices, normals, uvs\n\n\t\t\tfor ( i = 0, l = shapeVertices.length; i < l; i ++ ) {\n\n\t\t\t\tvar vertex = shapeVertices[ i ];\n\n\t\t\t\tvertices.push( vertex.x, vertex.y, 0 );\n\t\t\t\tnormals.push( 0, 0, 1 );\n\t\t\t\tuvs.push( vertex.x, vertex.y ); // world uvs\n\n\t\t\t}\n\n\t\t\t// incides\n\n\t\t\tfor ( i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar a = face[ 0 ] + indexOffset;\n\t\t\t\tvar b = face[ 1 ] + indexOffset;\n\t\t\t\tvar c = face[ 2 ] + indexOffset;\n\n\t\t\t\tindices.push( a, b, c );\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction EdgesGeometry( geometry, thresholdAngle ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'EdgesGeometry';\n\n\t\tthis.parameters = {\n\t\t\tthresholdAngle: thresholdAngle\n\t\t};\n\n\t\tthresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;\n\n\t\t// buffer\n\n\t\tvar vertices = [];\n\n\t\t// helper variables\n\n\t\tvar thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle );\n\t\tvar edge = [ 0, 0 ], edges = {};\n\t\tvar key, keys = [ 'a', 'b', 'c' ];\n\n\t\t// prepare source geometry\n\n\t\tvar geometry2;\n\n\t\tif ( geometry.isBufferGeometry ) {\n\n\t\t\tgeometry2 = new Geometry();\n\t\t\tgeometry2.fromBufferGeometry( geometry );\n\n\t\t} else {\n\n\t\t\tgeometry2 = geometry.clone();\n\n\t\t}\n\n\t\tgeometry2.mergeVertices();\n\t\tgeometry2.computeFaceNormals();\n\n\t\tvar sourceVertices = geometry2.vertices;\n\t\tvar faces = geometry2.faces;\n\n\t\t// now create a data structure where each entry represents an edge with its adjoining faces\n\n\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\tvar face = faces[ i ];\n\n\t\t\tfor ( var j = 0; j < 3; j ++ ) {\n\n\t\t\t\tedge[ 0 ] = face[ keys[ j ] ];\n\t\t\t\tedge[ 1 ] = face[ keys[ ( j + 1 ) % 3 ] ];\n\t\t\t\tedge.sort( sortFunction );\n\n\t\t\t\tkey = edge.toString();\n\n\t\t\t\tif ( edges[ key ] === undefined ) {\n\n\t\t\t\t\tedges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };\n\n\t\t\t\t} else {\n\n\t\t\t\t\tedges[ key ].face2 = i;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\t// generate vertices\n\n\t\tfor ( key in edges ) {\n\n\t\t\tvar e = edges[ key ];\n\n\t\t\t// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.\n\n\t\t\tif ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {\n\n\t\t\t\tvar vertex = sourceVertices[ e.index1 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\tvertex = sourceVertices[ e.index2 ];\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\n\t\t// custom array sort function\n\n\t\tfunction sortFunction( a, b ) {\n\n\t\t\treturn a - b;\n\n\t\t}\n\n\t}\n\n\tEdgesGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tEdgesGeometry.prototype.constructor = EdgesGeometry;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CylinderGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );\n\t\tthis.mergeVertices();\n\n\t}\n\n\tCylinderGeometry.prototype = Object.create( Geometry.prototype );\n\tCylinderGeometry.prototype.constructor = CylinderGeometry;\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CylinderBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradiusTop: radiusTop,\n\t\t\tradiusBottom: radiusBottom,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tvar scope = this;\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 20;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 20;\n\t\theight = height !== undefined ? height : 100;\n\n\t\tradialSegments = Math.floor( radialSegments ) || 8;\n\t\theightSegments = Math.floor( heightSegments ) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar index = 0;\n\t\tvar indexOffset = 0;\n\t\tvar indexArray = [];\n\t\tvar halfHeight = height / 2;\n\t\tvar groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\n\t\tif ( openEnded === false ) {\n\n\t\t\tif ( radiusTop > 0 ) generateCap( true );\n\t\t\tif ( radiusBottom > 0 ) generateCap( false );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t\tfunction generateTorso() {\n\n\t\t\tvar x, y;\n\t\t\tvar normal = new Vector3();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\tvar slope = ( radiusBottom - radiusTop ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor ( y = 0; y <= heightSegments; y ++ ) {\n\n\t\t\t\tvar indexRow = [];\n\n\t\t\t\tvar v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tvar radius = v * ( radiusBottom - radiusTop ) + radiusTop;\n\n\t\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\t\tvar u = x / radialSegments;\n\n\t\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tvar sinTheta = Math.sin( theta );\n\t\t\t\t\tvar cosTheta = Math.cos( theta );\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = - v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\tnormals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push( u, 1 - v );\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push( index ++ );\n\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push( indexRow );\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tfor ( y = 0; y < heightSegments; y ++ ) {\n\n\t\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\t\tvar a = indexArray[ y ][ x ];\n\t\t\t\t\tvar b = indexArray[ y + 1 ][ x ];\n\t\t\t\t\tvar c = indexArray[ y + 1 ][ x + 1 ];\n\t\t\t\t\tvar d = indexArray[ y ][ x + 1 ];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push( a, b, d );\n\t\t\t\t\tindices.push( b, c, d );\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, 0 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t\tfunction generateCap( top ) {\n\n\t\t\tvar x, centerIndexStart, centerIndexEnd;\n\n\t\t\tvar uv = new Vector2();\n\t\t\tvar vertex = new Vector3();\n\n\t\t\tvar groupCount = 0;\n\n\t\t\tvar radius = ( top === true ) ? radiusTop : radiusBottom;\n\t\t\tvar sign = ( top === true ) ? 1 : - 1;\n\n\t\t\t// save the index of the first center vertex\n\t\t\tcenterIndexStart = index;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor ( x = 1; x <= radialSegments; x ++ ) {\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push( 0, halfHeight * sign, 0 );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push( 0.5, 0.5 );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\n\t\t\tcenterIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor ( x = 0; x <= radialSegments; x ++ ) {\n\n\t\t\t\tvar u = x / radialSegments;\n\t\t\t\tvar theta = u * thetaLength + thetaStart;\n\n\t\t\t\tvar cosTheta = Math.cos( theta );\n\t\t\t\tvar sinTheta = Math.sin( theta );\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = ( cosTheta * 0.5 ) + 0.5;\n\t\t\t\tuv.y = ( sinTheta * 0.5 * sign ) + 0.5;\n\t\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex ++;\n\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor ( x = 0; x < radialSegments; x ++ ) {\n\n\t\t\t\tvar c = centerIndexStart + x;\n\t\t\t\tvar i = centerIndexEnd + x;\n\n\t\t\t\tif ( top === true ) {\n\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push( i, i + 1, c );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push( i + 1, i, c );\n\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t}\n\n\t}\n\n\tCylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeGeometry.prototype = Object.create( CylinderGeometry.prototype );\n\tConeGeometry.prototype.constructor = ConeGeometry;\n\n\t/**\n\t * @author: abelnation / http://github.com/abelnation\n\t */\n\n\tfunction ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {\n\n\t\tCylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );\n\n\t\tthis.type = 'ConeBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\theight: height,\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t\topenEnded: openEnded,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t}\n\n\tConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );\n\tConeBufferGeometry.prototype.constructor = ConeBufferGeometry;\n\n\t/**\n\t * @author hughes\n\t */\n\n\tfunction CircleGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tGeometry.call( this );\n\n\t\tthis.type = 'CircleGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tthis.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );\n\n\t}\n\n\tCircleGeometry.prototype = Object.create( Geometry.prototype );\n\tCircleGeometry.prototype.constructor = CircleGeometry;\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'CircleBufferGeometry';\n\n\t\tthis.parameters = {\n\t\t\tradius: radius,\n\t\t\tsegments: segments,\n\t\t\tthetaStart: thetaStart,\n\t\t\tthetaLength: thetaLength\n\t\t};\n\n\t\tradius = radius || 50;\n\t\tsegments = segments !== undefined ? Math.max( 3, segments ) : 8;\n\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\t// buffers\n\n\t\tvar indices = [];\n\t\tvar vertices = [];\n\t\tvar normals = [];\n\t\tvar uvs = [];\n\n\t\t// helper variables\n\n\t\tvar i, s;\n\t\tvar vertex = new Vector3();\n\t\tvar uv = new Vector2();\n\n\t\t// center point\n\n\t\tvertices.push( 0, 0, 0 );\n\t\tnormals.push( 0, 0, 1 );\n\t\tuvs.push( 0.5, 0.5 );\n\n\t\tfor ( s = 0, i = 3; s <= segments; s ++, i += 3 ) {\n\n\t\t\tvar segment = thetaStart + s / segments * thetaLength;\n\n\t\t\t// vertex\n\n\t\t\tvertex.x = radius * Math.cos( segment );\n\t\t\tvertex.y = radius * Math.sin( segment );\n\n\t\t\tvertices.push( vertex.x, vertex.y, vertex.z );\n\n\t\t\t// normal\n\n\t\t\tnormals.push( 0, 0, 1 );\n\n\t\t\t// uvs\n\n\t\t\tuv.x = ( vertices[ i ] / radius + 1 ) / 2;\n\t\t\tuv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;\n\n\t\t\tuvs.push( uv.x, uv.y );\n\n\t\t}\n\n\t\t// indices\n\n\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\tindices.push( i, i + 1, 0 );\n\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex( indices );\n\t\tthis.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tthis.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );\n\n\t}\n\n\tCircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tCircleBufferGeometry.prototype.constructor = CircleBufferGeometry;\n\n\n\n\tvar Geometries = Object.freeze({\n\t\tWireframeGeometry: WireframeGeometry,\n\t\tParametricGeometry: ParametricGeometry,\n\t\tParametricBufferGeometry: ParametricBufferGeometry,\n\t\tTetrahedronGeometry: TetrahedronGeometry,\n\t\tTetrahedronBufferGeometry: TetrahedronBufferGeometry,\n\t\tOctahedronGeometry: OctahedronGeometry,\n\t\tOctahedronBufferGeometry: OctahedronBufferGeometry,\n\t\tIcosahedronGeometry: IcosahedronGeometry,\n\t\tIcosahedronBufferGeometry: IcosahedronBufferGeometry,\n\t\tDodecahedronGeometry: DodecahedronGeometry,\n\t\tDodecahedronBufferGeometry: DodecahedronBufferGeometry,\n\t\tPolyhedronGeometry: PolyhedronGeometry,\n\t\tPolyhedronBufferGeometry: PolyhedronBufferGeometry,\n\t\tTubeGeometry: TubeGeometry,\n\t\tTubeBufferGeometry: TubeBufferGeometry,\n\t\tTorusKnotGeometry: TorusKnotGeometry,\n\t\tTorusKnotBufferGeometry: TorusKnotBufferGeometry,\n\t\tTorusGeometry: TorusGeometry,\n\t\tTorusBufferGeometry: TorusBufferGeometry,\n\t\tTextGeometry: TextGeometry,\n\t\tSphereGeometry: SphereGeometry,\n\t\tSphereBufferGeometry: SphereBufferGeometry,\n\t\tRingGeometry: RingGeometry,\n\t\tRingBufferGeometry: RingBufferGeometry,\n\t\tPlaneGeometry: PlaneGeometry,\n\t\tPlaneBufferGeometry: PlaneBufferGeometry,\n\t\tLatheGeometry: LatheGeometry,\n\t\tLatheBufferGeometry: LatheBufferGeometry,\n\t\tShapeGeometry: ShapeGeometry,\n\t\tShapeBufferGeometry: ShapeBufferGeometry,\n\t\tExtrudeGeometry: ExtrudeGeometry,\n\t\tEdgesGeometry: EdgesGeometry,\n\t\tConeGeometry: ConeGeometry,\n\t\tConeBufferGeometry: ConeBufferGeometry,\n\t\tCylinderGeometry: CylinderGeometry,\n\t\tCylinderBufferGeometry: CylinderBufferGeometry,\n\t\tCircleGeometry: CircleGeometry,\n\t\tCircleBufferGeometry: CircleBufferGeometry,\n\t\tBoxGeometry: BoxGeometry,\n\t\tBoxBufferGeometry: BoxBufferGeometry\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ShadowMaterial() {\n\n\t\tShaderMaterial.call( this, {\n\t\t\tuniforms: UniformsUtils.merge( [\n\t\t\t\tUniformsLib.lights,\n\t\t\t\t{\n\t\t\t\t\topacity: { value: 1.0 }\n\t\t\t\t}\n\t\t\t] ),\n\t\t\tvertexShader: ShaderChunk[ 'shadow_vert' ],\n\t\t\tfragmentShader: ShaderChunk[ 'shadow_frag' ]\n\t\t} );\n\n\t\tthis.lights = true;\n\t\tthis.transparent = true;\n\n\t\tObject.defineProperties( this, {\n\t\t\topacity: {\n\t\t\t\tenumerable: true,\n\t\t\t\tget: function () {\n\t\t\t\t\treturn this.uniforms.opacity.value;\n\t\t\t\t},\n\t\t\t\tset: function ( value ) {\n\t\t\t\t\tthis.uniforms.opacity.value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tShadowMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tShadowMaterial.prototype.constructor = ShadowMaterial;\n\n\tShadowMaterial.prototype.isShadowMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction RawShaderMaterial( parameters ) {\n\n\t\tShaderMaterial.call( this, parameters );\n\n\t\tthis.type = 'RawShaderMaterial';\n\n\t}\n\n\tRawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );\n\tRawShaderMaterial.prototype.constructor = RawShaderMaterial;\n\n\tRawShaderMaterial.prototype.isRawShaderMaterial = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MultiMaterial( materials ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.type = 'MultiMaterial';\n\n\t\tthis.materials = Array.isArray( materials ) ? materials : [];\n\n\t\tthis.visible = true;\n\n\t}\n\n\tMultiMaterial.prototype = {\n\n\t\tconstructor: MultiMaterial,\n\n\t\tisMultiMaterial: true,\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar output = {\n\t\t\t\tmetadata: {\n\t\t\t\t\tversion: 4.2,\n\t\t\t\t\ttype: 'material',\n\t\t\t\t\tgenerator: 'MaterialExporter'\n\t\t\t\t},\n\t\t\t\tuuid: this.uuid,\n\t\t\t\ttype: this.type,\n\t\t\t\tmaterials: []\n\t\t\t};\n\n\t\t\tvar materials = this.materials;\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tvar material = materials[ i ].toJSON( meta );\n\t\t\t\tdelete material.metadata;\n\n\t\t\t\toutput.materials.push( material );\n\n\t\t\t}\n\n\t\t\toutput.visible = this.visible;\n\n\t\t\treturn output;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\tvar material = new this.constructor();\n\n\t\t\tfor ( var i = 0; i < this.materials.length; i ++ ) {\n\n\t\t\t\tmaterial.materials.push( this.materials[ i ].clone() );\n\n\t\t\t}\n\n\t\t\tmaterial.visible = this.visible;\n\n\t\t\treturn material;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * color: ,\n\t * roughness: ,\n\t * metalness: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * roughnessMap: new THREE.Texture( ),\n\t *\n\t * metalnessMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),\n\t * envMapIntensity: \n\t *\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshStandardMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.type = 'MeshStandardMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.roughness = 0.5;\n\t\tthis.metalness = 0.5;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.roughnessMap = null;\n\n\t\tthis.metalnessMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.envMapIntensity = 1.0;\n\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshStandardMaterial.prototype = Object.create( Material.prototype );\n\tMeshStandardMaterial.prototype.constructor = MeshStandardMaterial;\n\n\tMeshStandardMaterial.prototype.isMeshStandardMaterial = true;\n\n\tMeshStandardMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'STANDARD': '' };\n\n\t\tthis.color.copy( source.color );\n\t\tthis.roughness = source.roughness;\n\t\tthis.metalness = source.metalness;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.roughnessMap = source.roughnessMap;\n\n\t\tthis.metalnessMap = source.metalnessMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.envMapIntensity = source.envMapIntensity;\n\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * reflectivity: \n\t * }\n\t */\n\n\tfunction MeshPhysicalMaterial( parameters ) {\n\n\t\tMeshStandardMaterial.call( this );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.type = 'MeshPhysicalMaterial';\n\n\t\tthis.reflectivity = 0.5; // maps to F0 = 0.04\n\n\t\tthis.clearCoat = 0.0;\n\t\tthis.clearCoatRoughness = 0.0;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );\n\tMeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;\n\n\tMeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;\n\n\tMeshPhysicalMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshStandardMaterial.prototype.copy.call( this, source );\n\n\t\tthis.defines = { 'PHYSICAL': '' };\n\n\t\tthis.reflectivity = source.reflectivity;\n\n\t\tthis.clearCoat = source.clearCoat;\n\t\tthis.clearCoatRoughness = source.clearCoatRoughness;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * specular: ,\n\t * shininess: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshPhongMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshPhongMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\t\tthis.specular = new Color( 0x111111 );\n\t\tthis.shininess = 30;\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshPhongMaterial.prototype = Object.create( Material.prototype );\n\tMeshPhongMaterial.prototype.constructor = MeshPhongMaterial;\n\n\tMeshPhongMaterial.prototype.isMeshPhongMaterial = true;\n\n\tMeshPhongMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\t\tthis.specular.copy( source.specular );\n\t\tthis.shininess = source.shininess;\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author takahirox / http://github.com/takahirox\n\t *\n\t * parameters = {\n\t * gradientMap: new THREE.Texture( )\n\t * }\n\t */\n\n\tfunction MeshToonMaterial( parameters ) {\n\n\t\tMeshPhongMaterial.call( this );\n\n\t\tthis.defines = { 'TOON': '' };\n\n\t\tthis.type = 'MeshToonMaterial';\n\n\t\tthis.gradientMap = null;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );\n\tMeshToonMaterial.prototype.constructor = MeshToonMaterial;\n\n\tMeshToonMaterial.prototype.isMeshToonMaterial = true;\n\n\tMeshToonMaterial.prototype.copy = function ( source ) {\n\n\t\tMeshPhongMaterial.prototype.copy.call( this, source );\n\n\t\tthis.gradientMap = source.gradientMap;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * parameters = {\n\t * opacity: ,\n\t *\n\t * bumpMap: new THREE.Texture( ),\n\t * bumpScale: ,\n\t *\n\t * normalMap: new THREE.Texture( ),\n\t * normalScale: ,\n\t *\n\t * displacementMap: new THREE.Texture( ),\n\t * displacementScale: ,\n\t * displacementBias: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: \n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshNormalMaterial( parameters ) {\n\n\t\tMaterial.call( this, parameters );\n\n\t\tthis.type = 'MeshNormalMaterial';\n\n\t\tthis.bumpMap = null;\n\t\tthis.bumpScale = 1;\n\n\t\tthis.normalMap = null;\n\t\tthis.normalScale = new Vector2( 1, 1 );\n\n\t\tthis.displacementMap = null;\n\t\tthis.displacementScale = 1;\n\t\tthis.displacementBias = 0;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\n\t\tthis.fog = false;\n\t\tthis.lights = false;\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshNormalMaterial.prototype = Object.create( Material.prototype );\n\tMeshNormalMaterial.prototype.constructor = MeshNormalMaterial;\n\n\tMeshNormalMaterial.prototype.isMeshNormalMaterial = true;\n\n\tMeshNormalMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.bumpMap = source.bumpMap;\n\t\tthis.bumpScale = source.bumpScale;\n\n\t\tthis.normalMap = source.normalMap;\n\t\tthis.normalScale.copy( source.normalScale );\n\n\t\tthis.displacementMap = source.displacementMap;\n\t\tthis.displacementScale = source.displacementScale;\n\t\tthis.displacementBias = source.displacementBias;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * map: new THREE.Texture( ),\n\t *\n\t * lightMap: new THREE.Texture( ),\n\t * lightMapIntensity: \n\t *\n\t * aoMap: new THREE.Texture( ),\n\t * aoMapIntensity: \n\t *\n\t * emissive: ,\n\t * emissiveIntensity: \n\t * emissiveMap: new THREE.Texture( ),\n\t *\n\t * specularMap: new THREE.Texture( ),\n\t *\n\t * alphaMap: new THREE.Texture( ),\n\t *\n\t * envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),\n\t * combine: THREE.Multiply,\n\t * reflectivity: ,\n\t * refractionRatio: ,\n\t *\n\t * wireframe: ,\n\t * wireframeLinewidth: ,\n\t *\n\t * skinning: ,\n\t * morphTargets: ,\n\t * morphNormals: \n\t * }\n\t */\n\n\tfunction MeshLambertMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'MeshLambertMaterial';\n\n\t\tthis.color = new Color( 0xffffff ); // diffuse\n\n\t\tthis.map = null;\n\n\t\tthis.lightMap = null;\n\t\tthis.lightMapIntensity = 1.0;\n\n\t\tthis.aoMap = null;\n\t\tthis.aoMapIntensity = 1.0;\n\n\t\tthis.emissive = new Color( 0x000000 );\n\t\tthis.emissiveIntensity = 1.0;\n\t\tthis.emissiveMap = null;\n\n\t\tthis.specularMap = null;\n\n\t\tthis.alphaMap = null;\n\n\t\tthis.envMap = null;\n\t\tthis.combine = MultiplyOperation;\n\t\tthis.reflectivity = 1;\n\t\tthis.refractionRatio = 0.98;\n\n\t\tthis.wireframe = false;\n\t\tthis.wireframeLinewidth = 1;\n\t\tthis.wireframeLinecap = 'round';\n\t\tthis.wireframeLinejoin = 'round';\n\n\t\tthis.skinning = false;\n\t\tthis.morphTargets = false;\n\t\tthis.morphNormals = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tMeshLambertMaterial.prototype = Object.create( Material.prototype );\n\tMeshLambertMaterial.prototype.constructor = MeshLambertMaterial;\n\n\tMeshLambertMaterial.prototype.isMeshLambertMaterial = true;\n\n\tMeshLambertMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.map = source.map;\n\n\t\tthis.lightMap = source.lightMap;\n\t\tthis.lightMapIntensity = source.lightMapIntensity;\n\n\t\tthis.aoMap = source.aoMap;\n\t\tthis.aoMapIntensity = source.aoMapIntensity;\n\n\t\tthis.emissive.copy( source.emissive );\n\t\tthis.emissiveMap = source.emissiveMap;\n\t\tthis.emissiveIntensity = source.emissiveIntensity;\n\n\t\tthis.specularMap = source.specularMap;\n\n\t\tthis.alphaMap = source.alphaMap;\n\n\t\tthis.envMap = source.envMap;\n\t\tthis.combine = source.combine;\n\t\tthis.reflectivity = source.reflectivity;\n\t\tthis.refractionRatio = source.refractionRatio;\n\n\t\tthis.wireframe = source.wireframe;\n\t\tthis.wireframeLinewidth = source.wireframeLinewidth;\n\t\tthis.wireframeLinecap = source.wireframeLinecap;\n\t\tthis.wireframeLinejoin = source.wireframeLinejoin;\n\n\t\tthis.skinning = source.skinning;\n\t\tthis.morphTargets = source.morphTargets;\n\t\tthis.morphNormals = source.morphNormals;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * parameters = {\n\t * color: ,\n\t * opacity: ,\n\t *\n\t * linewidth: ,\n\t *\n\t * scale: ,\n\t * dashSize: ,\n\t * gapSize: \n\t * }\n\t */\n\n\tfunction LineDashedMaterial( parameters ) {\n\n\t\tMaterial.call( this );\n\n\t\tthis.type = 'LineDashedMaterial';\n\n\t\tthis.color = new Color( 0xffffff );\n\n\t\tthis.linewidth = 1;\n\n\t\tthis.scale = 1;\n\t\tthis.dashSize = 3;\n\t\tthis.gapSize = 1;\n\n\t\tthis.lights = false;\n\n\t\tthis.setValues( parameters );\n\n\t}\n\n\tLineDashedMaterial.prototype = Object.create( Material.prototype );\n\tLineDashedMaterial.prototype.constructor = LineDashedMaterial;\n\n\tLineDashedMaterial.prototype.isLineDashedMaterial = true;\n\n\tLineDashedMaterial.prototype.copy = function ( source ) {\n\n\t\tMaterial.prototype.copy.call( this, source );\n\n\t\tthis.color.copy( source.color );\n\n\t\tthis.linewidth = source.linewidth;\n\n\t\tthis.scale = source.scale;\n\t\tthis.dashSize = source.dashSize;\n\t\tthis.gapSize = source.gapSize;\n\n\t\treturn this;\n\n\t};\n\n\n\n\tvar Materials = Object.freeze({\n\t\tShadowMaterial: ShadowMaterial,\n\t\tSpriteMaterial: SpriteMaterial,\n\t\tRawShaderMaterial: RawShaderMaterial,\n\t\tShaderMaterial: ShaderMaterial,\n\t\tPointsMaterial: PointsMaterial,\n\t\tMultiMaterial: MultiMaterial,\n\t\tMeshPhysicalMaterial: MeshPhysicalMaterial,\n\t\tMeshStandardMaterial: MeshStandardMaterial,\n\t\tMeshPhongMaterial: MeshPhongMaterial,\n\t\tMeshToonMaterial: MeshToonMaterial,\n\t\tMeshNormalMaterial: MeshNormalMaterial,\n\t\tMeshLambertMaterial: MeshLambertMaterial,\n\t\tMeshDepthMaterial: MeshDepthMaterial,\n\t\tMeshBasicMaterial: MeshBasicMaterial,\n\t\tLineDashedMaterial: LineDashedMaterial,\n\t\tLineBasicMaterial: LineBasicMaterial,\n\t\tMaterial: Material\n\t});\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tvar Cache = {\n\n\t\tenabled: false,\n\n\t\tfiles: {},\n\n\t\tadd: function ( key, file ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Adding key:', key );\n\n\t\t\tthis.files[ key ] = file;\n\n\t\t},\n\n\t\tget: function ( key ) {\n\n\t\t\tif ( this.enabled === false ) return;\n\n\t\t\t// console.log( 'THREE.Cache', 'Checking key:', key );\n\n\t\t\treturn this.files[ key ];\n\n\t\t},\n\n\t\tremove: function ( key ) {\n\n\t\t\tdelete this.files[ key ];\n\n\t\t},\n\n\t\tclear: function () {\n\n\t\t\tthis.files = {};\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LoadingManager( onLoad, onProgress, onError ) {\n\n\t\tvar scope = this;\n\n\t\tvar isLoading = false, itemsLoaded = 0, itemsTotal = 0;\n\n\t\tthis.onStart = undefined;\n\t\tthis.onLoad = onLoad;\n\t\tthis.onProgress = onProgress;\n\t\tthis.onError = onError;\n\n\t\tthis.itemStart = function ( url ) {\n\n\t\t\titemsTotal ++;\n\n\t\t\tif ( isLoading === false ) {\n\n\t\t\t\tif ( scope.onStart !== undefined ) {\n\n\t\t\t\t\tscope.onStart( url, itemsLoaded, itemsTotal );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tisLoading = true;\n\n\t\t};\n\n\t\tthis.itemEnd = function ( url ) {\n\n\t\t\titemsLoaded ++;\n\n\t\t\tif ( scope.onProgress !== undefined ) {\n\n\t\t\t\tscope.onProgress( url, itemsLoaded, itemsTotal );\n\n\t\t\t}\n\n\t\t\tif ( itemsLoaded === itemsTotal ) {\n\n\t\t\t\tisLoading = false;\n\n\t\t\t\tif ( scope.onLoad !== undefined ) {\n\n\t\t\t\t\tscope.onLoad();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.itemError = function ( url ) {\n\n\t\t\tif ( scope.onError !== undefined ) {\n\n\t\t\t\tscope.onError( url );\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\tvar DefaultLoadingManager = new LoadingManager();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FileLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FileLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\t// Check for data: URI\n\t\t\tvar dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;\n\t\t\tvar dataUriRegexResult = url.match( dataUriRegex );\n\n\t\t\t// Safari can not handle Data URIs through XMLHttpRequest so process manually\n\t\t\tif ( dataUriRegexResult ) {\n\n\t\t\t\tvar mimeType = dataUriRegexResult[ 1 ];\n\t\t\t\tvar isBase64 = !! dataUriRegexResult[ 2 ];\n\t\t\t\tvar data = dataUriRegexResult[ 3 ];\n\n\t\t\t\tdata = window.decodeURIComponent( data );\n\n\t\t\t\tif ( isBase64 ) data = window.atob( data );\n\n\t\t\t\ttry {\n\n\t\t\t\t\tvar response;\n\t\t\t\t\tvar responseType = ( this.responseType || '' ).toLowerCase();\n\n\t\t\t\t\tswitch ( responseType ) {\n\n\t\t\t\t\t\tcase 'arraybuffer':\n\t\t\t\t\t\tcase 'blob':\n\n\t\t\t\t\t\t \tresponse = new ArrayBuffer( data.length );\n\n\t\t\t\t\t\t\tvar view = new Uint8Array( response );\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\t\t\t\t\tview[ i ] = data.charCodeAt( i );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( responseType === 'blob' ) {\n\n\t\t\t\t\t\t\t\tresponse = new Blob( [ response ], { type: mimeType } );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'document':\n\n\t\t\t\t\t\t\tvar parser = new DOMParser();\n\t\t\t\t\t\t\tresponse = parser.parseFromString( data, mimeType );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'json':\n\n\t\t\t\t\t\t\tresponse = JSON.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault: // 'text' or other\n\n\t\t\t\t\t\t\tresponse = data;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\t// Wait for next browser tick\n\t\t\t\t\twindow.setTimeout( function () {\n\n\t\t\t\t\t\tif ( onError ) onError( error );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}, 0 );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tvar request = new XMLHttpRequest();\n\t\t\t\trequest.open( 'GET', url, true );\n\n\t\t\t\trequest.addEventListener( 'load', function ( event ) {\n\n\t\t\t\t\tvar response = event.target.response;\n\n\t\t\t\t\tCache.add( url, response );\n\n\t\t\t\t\tif ( this.status === 200 ) {\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else if ( this.status === 0 ) {\n\n\t\t\t\t\t\t// Some browsers return HTTP Status 0 when using non-http protocol\n\t\t\t\t\t\t// e.g. 'file://' or 'data://'. Handle as success.\n\n\t\t\t\t\t\tconsole.warn( 'THREE.FileLoader: HTTP Status 0 received.' );\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( response );\n\n\t\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( onProgress !== undefined ) {\n\n\t\t\t\t\trequest.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\t\t\tonProgress( event );\n\n\t\t\t\t\t}, false );\n\n\t\t\t\t}\n\n\t\t\t\trequest.addEventListener( 'error', function ( event ) {\n\n\t\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}, false );\n\n\t\t\t\tif ( this.responseType !== undefined ) request.responseType = this.responseType;\n\t\t\t\tif ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;\n\n\t\t\t\tif ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' );\n\n\t\t\t\trequest.send( null );\n\n\t\t\t}\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\treturn request;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetResponseType: function ( value ) {\n\n\t\t\tthis.responseType = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetWithCredentials: function ( value ) {\n\n\t\t\tthis.withCredentials = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetMimeType: function ( value ) {\n\n\t\t\tthis.mimeType = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t *\n\t * Abstract Base class to block based textures loader (dds, pvr, ...)\n\t */\n\n\tfunction CompressedTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( CompressedTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar images = [];\n\n\t\t\tvar texture = new CompressedTexture();\n\t\t\ttexture.image = images;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( url[ i ], function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\timages[ i ] = {\n\t\t\t\t\t\twidth: texDatas.width,\n\t\t\t\t\t\theight: texDatas.height,\n\t\t\t\t\t\tformat: texDatas.format,\n\t\t\t\t\t\tmipmaps: texDatas.mipmaps\n\t\t\t\t\t};\n\n\t\t\t\t\tloaded += 1;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\tif ( texDatas.mipmapCount === 1 )\n\t\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\tif ( Array.isArray( url ) ) {\n\n\t\t\t\tvar loaded = 0;\n\n\t\t\t\tfor ( var i = 0, il = url.length; i < il; ++ i ) {\n\n\t\t\t\t\tloadTexture( i );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// compressed cubemap texture stored in a single DDS file\n\n\t\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\t\tvar texDatas = scope._parser( buffer, true );\n\n\t\t\t\t\tif ( texDatas.isCubemap ) {\n\n\t\t\t\t\t\tvar faces = texDatas.mipmaps.length / texDatas.mipmapCount;\n\n\t\t\t\t\t\tfor ( var f = 0; f < faces; f ++ ) {\n\n\t\t\t\t\t\t\timages[ f ] = { mipmaps : [] };\n\n\t\t\t\t\t\t\tfor ( var i = 0; i < texDatas.mipmapCount; i ++ ) {\n\n\t\t\t\t\t\t\t\timages[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );\n\t\t\t\t\t\t\t\timages[ f ].format = texDatas.format;\n\t\t\t\t\t\t\t\timages[ f ].width = texDatas.width;\n\t\t\t\t\t\t\t\timages[ f ].height = texDatas.height;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttexture.image.width = texDatas.width;\n\t\t\t\t\t\ttexture.image.height = texDatas.height;\n\t\t\t\t\t\ttexture.mipmaps = texDatas.mipmaps;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( texDatas.mipmapCount === 1 ) {\n\n\t\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttexture.format = texDatas.format;\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t}, onProgress, onError );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author Nikos M. / https://github.com/foo123/\n\t *\n\t * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)\n\t */\n\n\tfunction DataTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\t// override in sub classes\n\t\tthis._parser = null;\n\n\t}\n\n\tObject.assign( DataTextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texture = new DataTexture();\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar texData = scope._parser( buffer );\n\n\t\t\t\tif ( ! texData ) return;\n\n\t\t\t\tif ( undefined !== texData.image ) {\n\n\t\t\t\t\ttexture.image = texData.image;\n\n\t\t\t\t} else if ( undefined !== texData.data ) {\n\n\t\t\t\t\ttexture.image.width = texData.width;\n\t\t\t\t\ttexture.image.height = texData.height;\n\t\t\t\t\ttexture.image.data = texData.data;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.wrapS = undefined !== texData.wrapS ? texData.wrapS : ClampToEdgeWrapping;\n\t\t\t\ttexture.wrapT = undefined !== texData.wrapT ? texData.wrapT : ClampToEdgeWrapping;\n\n\t\t\t\ttexture.magFilter = undefined !== texData.magFilter ? texData.magFilter : LinearFilter;\n\t\t\t\ttexture.minFilter = undefined !== texData.minFilter ? texData.minFilter : LinearMipMapLinearFilter;\n\n\t\t\t\ttexture.anisotropy = undefined !== texData.anisotropy ? texData.anisotropy : 1;\n\n\t\t\t\tif ( undefined !== texData.format ) {\n\n\t\t\t\t\ttexture.format = texData.format;\n\n\t\t\t\t}\n\t\t\t\tif ( undefined !== texData.type ) {\n\n\t\t\t\t\ttexture.type = texData.type;\n\n\t\t\t\t}\n\n\t\t\t\tif ( undefined !== texData.mipmaps ) {\n\n\t\t\t\t\ttexture.mipmaps = texData.mipmaps;\n\n\t\t\t\t}\n\n\t\t\t\tif ( 1 === texData.mipmapCount ) {\n\n\t\t\t\t\ttexture.minFilter = LinearFilter;\n\n\t\t\t\t}\n\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad ) onLoad( texture, texData );\n\n\t\t\t}, onProgress, onError );\n\n\n\t\t\treturn texture;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ImageLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( ImageLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( url === undefined ) url = '';\n\n\t\t\tif ( this.path !== undefined ) url = this.path + url;\n\n\t\t\tvar scope = this;\n\n\t\t\tvar cached = Cache.get( url );\n\n\t\t\tif ( cached !== undefined ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\tsetTimeout( function () {\n\n\t\t\t\t\tif ( onLoad ) onLoad( cached );\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, 0 );\n\n\t\t\t\treturn cached;\n\n\t\t\t}\n\n\t\t\tvar image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );\n\n\t\t\timage.addEventListener( 'load', function () {\n\n\t\t\t\tCache.add( url, this );\n\n\t\t\t\tif ( onLoad ) onLoad( this );\n\n\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t}, false );\n\n\t\t\t/*\n\t\t\timage.addEventListener( 'progress', function ( event ) {\n\n\t\t\t\tif ( onProgress ) onProgress( event );\n\n\t\t\t}, false );\n\t\t\t*/\n\n\t\t\timage.addEventListener( 'error', function ( event ) {\n\n\t\t\t\tif ( onError ) onError( event );\n\n\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t}, false );\n\n\t\t\tif ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;\n\n\t\t\tscope.manager.itemStart( url );\n\n\t\t\timage.src = url;\n\n\t\t\treturn image;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction CubeTextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( CubeTextureLoader.prototype, {\n\n\t\tload: function ( urls, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new CubeTexture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\n\t\t\tvar loaded = 0;\n\n\t\t\tfunction loadTexture( i ) {\n\n\t\t\t\tloader.load( urls[ i ], function ( image ) {\n\n\t\t\t\t\ttexture.images[ i ] = image;\n\n\t\t\t\t\tloaded ++;\n\n\t\t\t\t\tif ( loaded === 6 ) {\n\n\t\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\t\tif ( onLoad ) onLoad( texture );\n\n\t\t\t\t\t}\n\n\t\t\t\t}, undefined, onError );\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < urls.length; ++ i ) {\n\n\t\t\t\tloadTexture( i );\n\n\t\t\t}\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction TextureLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( TextureLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar texture = new Texture();\n\n\t\t\tvar loader = new ImageLoader( this.manager );\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.load( url, function ( image ) {\n\n\t\t\t\t// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.\n\t\t\t\tvar isJPEG = url.search( /\\.(jpg|jpeg)$/ ) > 0 || url.search( /^data\\:image\\/jpeg/ ) === 0;\n\n\t\t\t\ttexture.format = isJPEG ? RGBFormat : RGBAFormat;\n\t\t\t\ttexture.image = image;\n\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\tif ( onLoad !== undefined ) {\n\n\t\t\t\t\tonLoad( texture );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetPath: function ( value ) {\n\n\t\t\tthis.path = value;\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Light( color, intensity ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Light';\n\n\t\tthis.color = new Color( color );\n\t\tthis.intensity = intensity !== undefined ? intensity : 1;\n\n\t\tthis.receiveShadow = undefined;\n\n\t}\n\n\tLight.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Light,\n\n\t\tisLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tObject3D.prototype.copy.call( this, source );\n\n\t\t\tthis.color.copy( source.color );\n\t\t\tthis.intensity = source.intensity;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\ttoJSON: function ( meta ) {\n\n\t\t\tvar data = Object3D.prototype.toJSON.call( this, meta );\n\n\t\t\tdata.object.color = this.color.getHex();\n\t\t\tdata.object.intensity = this.intensity;\n\n\t\t\tif ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex();\n\n\t\t\tif ( this.distance !== undefined ) data.object.distance = this.distance;\n\t\t\tif ( this.angle !== undefined ) data.object.angle = this.angle;\n\t\t\tif ( this.decay !== undefined ) data.object.decay = this.decay;\n\t\t\tif ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra;\n\n\t\t\tif ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON();\n\n\t\t\treturn data;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction HemisphereLight( skyColor, groundColor, intensity ) {\n\n\t\tLight.call( this, skyColor, intensity );\n\n\t\tthis.type = 'HemisphereLight';\n\n\t\tthis.castShadow = undefined;\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.groundColor = new Color( groundColor );\n\n\t}\n\n\tHemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: HemisphereLight,\n\n\t\tisHemisphereLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.groundColor.copy( source.groundColor );\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction LightShadow( camera ) {\n\n\t\tthis.camera = camera;\n\n\t\tthis.bias = 0;\n\t\tthis.radius = 1;\n\n\t\tthis.mapSize = new Vector2( 512, 512 );\n\n\t\tthis.map = null;\n\t\tthis.matrix = new Matrix4();\n\n\t}\n\n\tObject.assign( LightShadow.prototype, {\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.camera = source.camera.clone();\n\n\t\t\tthis.bias = source.bias;\n\t\t\tthis.radius = source.radius;\n\n\t\t\tthis.mapSize.copy( source.mapSize );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\ttoJSON: function () {\n\n\t\t\tvar object = {};\n\n\t\t\tif ( this.bias !== 0 ) object.bias = this.bias;\n\t\t\tif ( this.radius !== 1 ) object.radius = this.radius;\n\t\t\tif ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray();\n\n\t\t\tobject.camera = this.camera.toJSON( false ).object;\n\t\t\tdelete object.camera.matrix;\n\n\t\t\treturn object;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction SpotLightShadow() {\n\n\t\tLightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );\n\n\t}\n\n\tSpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: SpotLightShadow,\n\n\t\tisSpotLightShadow: true,\n\n\t\tupdate: function ( light ) {\n\n\t\t\tvar fov = _Math.RAD2DEG * 2 * light.angle;\n\t\t\tvar aspect = this.mapSize.width / this.mapSize.height;\n\t\t\tvar far = light.distance || 500;\n\n\t\t\tvar camera = this.camera;\n\n\t\t\tif ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {\n\n\t\t\t\tcamera.fov = fov;\n\t\t\t\tcamera.aspect = aspect;\n\t\t\t\tcamera.far = far;\n\t\t\t\tcamera.updateProjectionMatrix();\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction SpotLight( color, intensity, distance, angle, penumbra, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'SpotLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * Math.PI;\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / Math.PI;\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.angle = ( angle !== undefined ) ? angle : Math.PI / 3;\n\t\tthis.penumbra = ( penumbra !== undefined ) ? penumbra : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new SpotLightShadow();\n\n\t}\n\n\tSpotLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: SpotLight,\n\n\t\tisSpotLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.angle = source.angle;\n\t\t\tthis.penumbra = source.penumbra;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\n\tfunction PointLight( color, intensity, distance, decay ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'PointLight';\n\n\t\tObject.defineProperty( this, 'power', {\n\t\t\tget: function () {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\treturn this.intensity * 4 * Math.PI;\n\n\t\t\t},\n\t\t\tset: function ( power ) {\n\t\t\t\t// intensity = power per solid angle.\n\t\t\t\t// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf\n\t\t\t\tthis.intensity = power / ( 4 * Math.PI );\n\t\t\t}\n\t\t} );\n\n\t\tthis.distance = ( distance !== undefined ) ? distance : 0;\n\t\tthis.decay = ( decay !== undefined ) ? decay : 1;\t// for physically correct lights, should be 2.\n\n\t\tthis.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\tPointLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: PointLight,\n\n\t\tisPointLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.distance = source.distance;\n\t\t\tthis.decay = source.decay;\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction DirectionalLightShadow( ) {\n\n\t\tLightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );\n\n\t}\n\n\tDirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {\n\n\t\tconstructor: DirectionalLightShadow\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction DirectionalLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'DirectionalLight';\n\n\t\tthis.position.copy( Object3D.DefaultUp );\n\t\tthis.updateMatrix();\n\n\t\tthis.target = new Object3D();\n\n\t\tthis.shadow = new DirectionalLightShadow();\n\n\t}\n\n\tDirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: DirectionalLight,\n\n\t\tisDirectionalLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.target = source.target.clone();\n\n\t\t\tthis.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AmbientLight( color, intensity ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'AmbientLight';\n\n\t\tthis.castShadow = undefined;\n\n\t}\n\n\tAmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: AmbientLight,\n\n\t\tisAmbientLight: true\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tvar AnimationUtils = {\n\n\t\t// same as Array.prototype.slice, but also works on typed arrays\n\t\tarraySlice: function( array, from, to ) {\n\n\t\t\tif ( AnimationUtils.isTypedArray( array ) ) {\n\n\t\t\t\treturn new array.constructor( array.subarray( from, to ) );\n\n\t\t\t}\n\n\t\t\treturn array.slice( from, to );\n\n\t\t},\n\n\t\t// converts an array to a specific type\n\t\tconvertArray: function( array, type, forceClone ) {\n\n\t\t\tif ( ! array || // let 'undefined' and 'null' pass\n\t\t\t\t\t! forceClone && array.constructor === type ) return array;\n\n\t\t\tif ( typeof type.BYTES_PER_ELEMENT === 'number' ) {\n\n\t\t\t\treturn new type( array ); // create typed array\n\n\t\t\t}\n\n\t\t\treturn Array.prototype.slice.call( array ); // create Array\n\n\t\t},\n\n\t\tisTypedArray: function( object ) {\n\n\t\t\treturn ArrayBuffer.isView( object ) &&\n\t\t\t\t\t! ( object instanceof DataView );\n\n\t\t},\n\n\t\t// returns an array by which times and values can be sorted\n\t\tgetKeyframeOrder: function( times ) {\n\n\t\t\tfunction compareTime( i, j ) {\n\n\t\t\t\treturn times[ i ] - times[ j ];\n\n\t\t\t}\n\n\t\t\tvar n = times.length;\n\t\t\tvar result = new Array( n );\n\t\t\tfor ( var i = 0; i !== n; ++ i ) result[ i ] = i;\n\n\t\t\tresult.sort( compareTime );\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// uses the array previously returned by 'getKeyframeOrder' to sort data\n\t\tsortedArray: function( values, stride, order ) {\n\n\t\t\tvar nValues = values.length;\n\t\t\tvar result = new values.constructor( nValues );\n\n\t\t\tfor ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {\n\n\t\t\t\tvar srcOffset = order[ i ] * stride;\n\n\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\tresult[ dstOffset ++ ] = values[ srcOffset + j ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// function for parsing AOS keyframe formats\n\t\tflattenJSON: function( jsonKeys, times, values, valuePropertyName ) {\n\n\t\t\tvar i = 1, key = jsonKeys[ 0 ];\n\n\t\t\twhile ( key !== undefined && key[ valuePropertyName ] === undefined ) {\n\n\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t}\n\n\t\t\tif ( key === undefined ) return; // no data\n\n\t\t\tvar value = key[ valuePropertyName ];\n\t\t\tif ( value === undefined ) return; // no data\n\n\t\t\tif ( Array.isArray( value ) ) {\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push.apply( values, value ); // push all elements\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else if ( value.toArray !== undefined ) {\n\t\t\t\t// ...assume THREE.Math-ish\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalue.toArray( values, values.length );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t} else {\n\t\t\t\t// otherwise push as-is\n\n\t\t\t\tdo {\n\n\t\t\t\t\tvalue = key[ valuePropertyName ];\n\n\t\t\t\t\tif ( value !== undefined ) {\n\n\t\t\t\t\t\ttimes.push( key.time );\n\t\t\t\t\t\tvalues.push( value );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tkey = jsonKeys[ i ++ ];\n\n\t\t\t\t} while ( key !== undefined );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Abstract base class of interpolants over parametric samples.\n\t *\n\t * The parameter domain is one dimensional, typically the time or a path\n\t * along a curve defined by the data.\n\t *\n\t * The sample values can have any dimensionality and derived classes may\n\t * apply special interpretations to the data.\n\t *\n\t * This class provides the interval seek in a Template Method, deferring\n\t * the actual interpolation to derived classes.\n\t *\n\t * Time complexity is O(1) for linear access crossing at most two points\n\t * and O(log N) for random access, where N is the number of positions.\n\t *\n\t * References:\n\t *\n\t * \t\thttp://www.oodesign.com/template-method-pattern.html\n\t *\n\t * @author tschw\n\t */\n\n\tfunction Interpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tthis.parameterPositions = parameterPositions;\n\t\tthis._cachedIndex = 0;\n\n\t\tthis.resultBuffer = resultBuffer !== undefined ?\n\t\t\t\tresultBuffer : new sampleValues.constructor( sampleSize );\n\t\tthis.sampleValues = sampleValues;\n\t\tthis.valueSize = sampleSize;\n\n\t}\n\n\tInterpolant.prototype = {\n\n\t\tconstructor: Interpolant,\n\n\t\tevaluate: function( t ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\ti1 = this._cachedIndex,\n\n\t\t\t\tt1 = pp[ i1 ],\n\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\tvalidate_interval: {\n\n\t\t\t\tseek: {\n\n\t\t\t\t\tvar right;\n\n\t\t\t\t\tlinear_scan: {\n\t//- See http://jsperf.com/comparison-to-undefined/3\n\t//- slower code:\n\t//-\n\t//- \t\t\t\tif ( t >= t1 || t1 === undefined ) {\n\t\t\t\t\t\tforward_scan: if ( ! ( t < t1 ) ) {\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 + 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\t\t\t\tif ( t < t0 ) break forward_scan;\n\n\t\t\t\t\t\t\t\t\t// after end\n\n\t\t\t\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t, t0 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt0 = t1;\n\t\t\t\t\t\t\t\tt1 = pp[ ++ i1 ];\n\n\t\t\t\t\t\t\t\tif ( t < t1 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the right side of the index\n\t\t\t\t\t\t\tright = pp.length;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t//- slower code:\n\t//-\t\t\t\t\tif ( t < t0 || t0 === undefined ) {\n\t\t\t\t\t\tif ( ! ( t >= t0 ) ) {\n\n\t\t\t\t\t\t\t// looping?\n\n\t\t\t\t\t\t\tvar t1global = pp[ 1 ];\n\n\t\t\t\t\t\t\tif ( t < t1global ) {\n\n\t\t\t\t\t\t\t\ti1 = 2; // + 1, using the scan for the details\n\t\t\t\t\t\t\t\tt0 = t1global;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// linear reverse scan\n\n\t\t\t\t\t\t\tfor ( var giveUpAt = i1 - 2; ;) {\n\n\t\t\t\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\t\t\t\t// before start\n\n\t\t\t\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ( i1 === giveUpAt ) break; // this loop\n\n\t\t\t\t\t\t\t\tt1 = t0;\n\t\t\t\t\t\t\t\tt0 = pp[ -- i1 - 1 ];\n\n\t\t\t\t\t\t\t\tif ( t >= t0 ) {\n\n\t\t\t\t\t\t\t\t\t// we have arrived at the sought interval\n\t\t\t\t\t\t\t\t\tbreak seek;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// prepare binary search on the left side of the index\n\t\t\t\t\t\t\tright = i1;\n\t\t\t\t\t\t\ti1 = 0;\n\t\t\t\t\t\t\tbreak linear_scan;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// the interval is valid\n\n\t\t\t\t\t\tbreak validate_interval;\n\n\t\t\t\t\t} // linear scan\n\n\t\t\t\t\t// binary search\n\n\t\t\t\t\twhile ( i1 < right ) {\n\n\t\t\t\t\t\tvar mid = ( i1 + right ) >>> 1;\n\n\t\t\t\t\t\tif ( t < pp[ mid ] ) {\n\n\t\t\t\t\t\t\tright = mid;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\ti1 = mid + 1;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tt1 = pp[ i1 ];\n\t\t\t\t\tt0 = pp[ i1 - 1 ];\n\n\t\t\t\t\t// check boundary cases, again\n\n\t\t\t\t\tif ( t0 === undefined ) {\n\n\t\t\t\t\t\tthis._cachedIndex = 0;\n\t\t\t\t\t\treturn this.beforeStart_( 0, t, t1 );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( t1 === undefined ) {\n\n\t\t\t\t\t\ti1 = pp.length;\n\t\t\t\t\t\tthis._cachedIndex = i1;\n\t\t\t\t\t\treturn this.afterEnd_( i1 - 1, t0, t );\n\n\t\t\t\t\t}\n\n\t\t\t\t} // seek\n\n\t\t\t\tthis._cachedIndex = i1;\n\n\t\t\t\tthis.intervalChanged_( i1, t0, t1 );\n\n\t\t\t} // validate_interval\n\n\t\t\treturn this.interpolate_( i1, t0, t, t1 );\n\n\t\t},\n\n\t\tsettings: null, // optional, subclass-specific settings structure\n\t\t// Note: The indirection allows central control of many interpolants.\n\n\t\t// --- Protected interface\n\n\t\tDefaultSettings_: {},\n\n\t\tgetSettings_: function() {\n\n\t\t\treturn this.settings || this.DefaultSettings_;\n\n\t\t},\n\n\t\tcopySampleValue_: function( index ) {\n\n\t\t\t// copies a sample value to the result buffer\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = index * stride;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] = values[ offset + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t},\n\n\t\t// Template methods for derived classes:\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tthrow new Error( \"call to abstract method\" );\n\t\t\t// implementations shall return this.resultBuffer\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\t// empty\n\n\t\t}\n\n\t};\n\n\tObject.assign( Interpolant.prototype, {\n\n\t\tbeforeStart_: //( 0, t, t0 ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_,\n\n\t\tafterEnd_: //( N-1, tN-1, t ), returns this.resultBuffer\n\t\t\tInterpolant.prototype.copySampleValue_\n\n\t} );\n\n\t/**\n\t * Fast and simple cubic spline interpolant.\n\t *\n\t * It was derived from a Hermitian construction setting the first derivative\n\t * at each sample position to the linear slope between neighboring positions\n\t * over their parameter interval.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction CubicInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t\tthis._weightPrev = -0;\n\t\tthis._offsetPrev = -0;\n\t\tthis._weightNext = -0;\n\t\tthis._offsetNext = -0;\n\n\t}\n\n\tCubicInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: CubicInterpolant,\n\n\t\tDefaultSettings_: {\n\n\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\n\t\t},\n\n\t\tintervalChanged_: function( i1, t0, t1 ) {\n\n\t\t\tvar pp = this.parameterPositions,\n\t\t\t\tiPrev = i1 - 2,\n\t\t\t\tiNext = i1 + 1,\n\n\t\t\t\ttPrev = pp[ iPrev ],\n\t\t\t\ttNext = pp[ iNext ];\n\n\t\t\tif ( tPrev === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingStart ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(t0) = 0\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = 2 * t0 - t1;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiPrev = pp.length - 2;\n\t\t\t\t\t\ttPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(t0) = 0 a.k.a. Natural Spline\n\t\t\t\t\t\tiPrev = i1;\n\t\t\t\t\t\ttPrev = t1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tNext === undefined ) {\n\n\t\t\t\tswitch ( this.getSettings_().endingEnd ) {\n\n\t\t\t\t\tcase ZeroSlopeEnding:\n\n\t\t\t\t\t\t// f'(tN) = 0\n\t\t\t\t\t\tiNext = i1;\n\t\t\t\t\t\ttNext = 2 * t1 - t0;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase WrapAroundEnding:\n\n\t\t\t\t\t\t// use the other end of the curve\n\t\t\t\t\t\tiNext = 1;\n\t\t\t\t\t\ttNext = t1 + pp[ 1 ] - pp[ 0 ];\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: // ZeroCurvatureEnding\n\n\t\t\t\t\t\t// f''(tN) = 0, a.k.a. Natural Spline\n\t\t\t\t\t\tiNext = i1 - 1;\n\t\t\t\t\t\ttNext = t0;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar halfDt = ( t1 - t0 ) * 0.5,\n\t\t\t\tstride = this.valueSize;\n\n\t\t\tthis._weightPrev = halfDt / ( t0 - tPrev );\n\t\t\tthis._weightNext = halfDt / ( tNext - t1 );\n\t\t\tthis._offsetPrev = iPrev * stride;\n\t\t\tthis._offsetNext = iNext * stride;\n\n\t\t},\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\to1 = i1 * stride,\t\to0 = o1 - stride,\n\t\t\t\toP = this._offsetPrev, \toN = this._offsetNext,\n\t\t\t\twP = this._weightPrev,\twN = this._weightNext,\n\n\t\t\t\tp = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tpp = p * p,\n\t\t\t\tppp = pp * p;\n\n\t\t\t// evaluate polynomials\n\n\t\t\tvar sP = - wP * ppp + 2 * wP * pp - wP * p;\n\t\t\tvar s0 = ( 1 + wP ) * ppp + (-1.5 - 2 * wP ) * pp + ( -0.5 + wP ) * p + 1;\n\t\t\tvar s1 = (-1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;\n\t\t\tvar sN = wN * ppp - wN * pp;\n\n\t\t\t// combine data linearly\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tsP * values[ oP + i ] +\n\t\t\t\t\t\ts0 * values[ o0 + i ] +\n\t\t\t\t\t\ts1 * values[ o1 + i ] +\n\t\t\t\t\t\tsN * values[ oN + i ];\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author tschw\n\t */\n\n\tfunction LinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: LinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset1 = i1 * stride,\n\t\t\t\toffset0 = offset1 - stride,\n\n\t\t\t\tweight1 = ( t - t0 ) / ( t1 - t0 ),\n\t\t\t\tweight0 = 1 - weight1;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tresult[ i ] =\n\t\t\t\t\t\tvalues[ offset0 + i ] * weight0 +\n\t\t\t\t\t\tvalues[ offset1 + i ] * weight1;\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Interpolant that evaluates to the sample value at the position preceeding\n\t * the parameter.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction DiscreteInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tDiscreteInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: DiscreteInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\treturn this.copySampleValue_( i1 - 1 );\n\n\t\t}\n\n\t} );\n\n\tvar KeyframeTrackPrototype;\n\n\tKeyframeTrackPrototype = {\n\n\t\tTimeBufferType: Float32Array,\n\t\tValueBufferType: Float32Array,\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodDiscrete: function ( result ) {\n\n\t\t\treturn new DiscreteInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodLinear: function ( result ) {\n\n\t\t\treturn new LinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: function ( result ) {\n\n\t\t\treturn new CubicInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tsetInterpolation: function ( interpolation ) {\n\n\t\t\tvar factoryMethod;\n\n\t\t\tswitch ( interpolation ) {\n\n\t\t\t\tcase InterpolateDiscrete:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodDiscrete;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateLinear:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodLinear;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase InterpolateSmooth:\n\n\t\t\t\t\tfactoryMethod = this.InterpolantFactoryMethodSmooth;\n\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\tif ( factoryMethod === undefined ) {\n\n\t\t\t\tvar message = \"unsupported interpolation for \" +\n\t\t\t\t\t\tthis.ValueTypeName + \" keyframe track named \" + this.name;\n\n\t\t\t\tif ( this.createInterpolant === undefined ) {\n\n\t\t\t\t\t// fall back to default, unless the default itself is messed up\n\t\t\t\t\tif ( interpolation !== this.DefaultInterpolation ) {\n\n\t\t\t\t\t\tthis.setInterpolation( this.DefaultInterpolation );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tthrow new Error( message ); // fatal, in this case\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconsole.warn( message );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.createInterpolant = factoryMethod;\n\n\t\t},\n\n\t\tgetInterpolation: function () {\n\n\t\t\tswitch ( this.createInterpolant ) {\n\n\t\t\t\tcase this.InterpolantFactoryMethodDiscrete:\n\n\t\t\t\t\treturn InterpolateDiscrete;\n\n\t\t\t\tcase this.InterpolantFactoryMethodLinear:\n\n\t\t\t\t\treturn InterpolateLinear;\n\n\t\t\t\tcase this.InterpolantFactoryMethodSmooth:\n\n\t\t\t\t\treturn InterpolateSmooth;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetValueSize: function () {\n\n\t\t\treturn this.values.length / this.times.length;\n\n\t\t},\n\n\t\t// move all keyframes either forwards or backwards in time\n\t\tshift: function ( timeOffset ) {\n\n\t\t\tif ( timeOffset !== 0.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] += timeOffset;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// scale all keyframe times by a factor (useful for frame <-> seconds conversions)\n\t\tscale: function ( timeScale ) {\n\n\t\t\tif ( timeScale !== 1.0 ) {\n\n\t\t\t\tvar times = this.times;\n\n\t\t\t\tfor ( var i = 0, n = times.length; i !== n; ++ i ) {\n\n\t\t\t\t\ttimes[ i ] *= timeScale;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// removes keyframes before and after animation without changing any values within the range [startTime, endTime].\n\t\t// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values\n\t\ttrim: function ( startTime, endTime ) {\n\n\t\t\tvar times = this.times,\n\t\t\t\tnKeys = times.length,\n\t\t\t\tfrom = 0,\n\t\t\t\tto = nKeys - 1;\n\n\t\t\twhile ( from !== nKeys && times[ from ] < startTime ) ++ from;\n\t\t\twhile ( to !== - 1 && times[ to ] > endTime ) -- to;\n\n\t\t\t++ to; // inclusive -> exclusive bound\n\n\t\t\tif ( from !== 0 || to !== nKeys ) {\n\n\t\t\t\t// empty tracks are forbidden, so keep at least one keyframe\n\t\t\t\tif ( from >= to ) to = Math.max( to, 1 ), from = to - 1;\n\n\t\t\t\tvar stride = this.getValueSize();\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, from, to );\n\t\t\t\tthis.values = AnimationUtils.\n\t\t\t\t\t\tarraySlice( this.values, from * stride, to * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable\n\t\tvalidate: function () {\n\n\t\t\tvar valid = true;\n\n\t\t\tvar valueSize = this.getValueSize();\n\t\t\tif ( valueSize - Math.floor( valueSize ) !== 0 ) {\n\n\t\t\t\tconsole.error( \"invalid value size in track\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\n\t\t\t\tnKeys = times.length;\n\n\t\t\tif ( nKeys === 0 ) {\n\n\t\t\t\tconsole.error( \"track is empty\", this );\n\t\t\t\tvalid = false;\n\n\t\t\t}\n\n\t\t\tvar prevTime = null;\n\n\t\t\tfor ( var i = 0; i !== nKeys; i ++ ) {\n\n\t\t\t\tvar currTime = times[ i ];\n\n\t\t\t\tif ( typeof currTime === 'number' && isNaN( currTime ) ) {\n\n\t\t\t\t\tconsole.error( \"time is not a valid number\", this, i, currTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif ( prevTime !== null && prevTime > currTime ) {\n\n\t\t\t\t\tconsole.error( \"out of order keys\", this, i, currTime, prevTime );\n\t\t\t\t\tvalid = false;\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tprevTime = currTime;\n\n\t\t\t}\n\n\t\t\tif ( values !== undefined ) {\n\n\t\t\t\tif ( AnimationUtils.isTypedArray( values ) ) {\n\n\t\t\t\t\tfor ( var i = 0, n = values.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tvar value = values[ i ];\n\n\t\t\t\t\t\tif ( isNaN( value ) ) {\n\n\t\t\t\t\t\t\tconsole.error( \"value is not a valid number\", this, i, value );\n\t\t\t\t\t\t\tvalid = false;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn valid;\n\n\t\t},\n\n\t\t// removes equivalent sequential keys as common in morph target sequences\n\t\t// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)\n\t\toptimize: function () {\n\n\t\t\tvar times = this.times,\n\t\t\t\tvalues = this.values,\n\t\t\t\tstride = this.getValueSize(),\n\n\t\t\t\tsmoothInterpolation = this.getInterpolation() === InterpolateSmooth,\n\n\t\t\t\twriteIndex = 1,\n\t\t\t\tlastIndex = times.length - 1;\n\n\t\t\tfor ( var i = 1; i < lastIndex; ++ i ) {\n\n\t\t\t\tvar keep = false;\n\n\t\t\t\tvar time = times[ i ];\n\t\t\t\tvar timeNext = times[ i + 1 ];\n\n\t\t\t\t// remove adjacent keyframes scheduled at the same time\n\n\t\t\t\tif ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {\n\n\t\t\t\t\tif ( ! smoothInterpolation ) {\n\n\t\t\t\t\t\t// remove unnecessary keyframes same as their neighbors\n\n\t\t\t\t\t\tvar offset = i * stride,\n\t\t\t\t\t\t\toffsetP = offset - stride,\n\t\t\t\t\t\t\toffsetN = offset + stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j ) {\n\n\t\t\t\t\t\t\tvar value = values[ offset + j ];\n\n\t\t\t\t\t\t\tif ( value !== values[ offsetP + j ] ||\n\t\t\t\t\t\t\t\t\tvalue !== values[ offsetN + j ] ) {\n\n\t\t\t\t\t\t\t\tkeep = true;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else keep = true;\n\n\t\t\t\t}\n\n\t\t\t\t// in-place compaction\n\n\t\t\t\tif ( keep ) {\n\n\t\t\t\t\tif ( i !== writeIndex ) {\n\n\t\t\t\t\t\ttimes[ writeIndex ] = times[ i ];\n\n\t\t\t\t\t\tvar readOffset = i * stride,\n\t\t\t\t\t\t\twriteOffset = writeIndex * stride;\n\n\t\t\t\t\t\tfor ( var j = 0; j !== stride; ++ j )\n\n\t\t\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\t++ writeIndex;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// flush last keyframe (compaction looks ahead)\n\n\t\t\tif ( lastIndex > 0 ) {\n\n\t\t\t\ttimes[ writeIndex ] = times[ lastIndex ];\n\n\t\t\t\tfor ( var readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j )\n\n\t\t\t\t\tvalues[ writeOffset + j ] = values[ readOffset + j ];\n\n\t\t\t\t++ writeIndex;\n\n\t\t\t}\n\n\t\t\tif ( writeIndex !== times.length ) {\n\n\t\t\t\tthis.times = AnimationUtils.arraySlice( times, 0, writeIndex );\n\t\t\t\tthis.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\tfunction KeyframeTrackConstructor( name, times, values, interpolation ) {\n\n\t\tif( name === undefined ) throw new Error( \"track name is undefined\" );\n\n\t\tif( times === undefined || times.length === 0 ) {\n\n\t\t\tthrow new Error( \"no keyframes in track named \" + name );\n\n\t\t}\n\n\t\tthis.name = name;\n\n\t\tthis.times = AnimationUtils.convertArray( times, this.TimeBufferType );\n\t\tthis.values = AnimationUtils.convertArray( values, this.ValueBufferType );\n\n\t\tthis.setInterpolation( interpolation || this.DefaultInterpolation );\n\n\t\tthis.validate();\n\t\tthis.optimize();\n\n\t}\n\n\t/**\n\t *\n\t * A Track of vectored keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction VectorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tVectorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: VectorKeyframeTrack,\n\n\t\tValueTypeName: 'vector'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t * Spherical linear unit quaternion interpolant.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction QuaternionLinearInterpolant(\n\t\t\tparameterPositions, sampleValues, sampleSize, resultBuffer ) {\n\n\t\tInterpolant.call(\n\t\t\t\tthis, parameterPositions, sampleValues, sampleSize, resultBuffer );\n\n\t}\n\n\tQuaternionLinearInterpolant.prototype =\n\t\t\tObject.assign( Object.create( Interpolant.prototype ), {\n\n\t\tconstructor: QuaternionLinearInterpolant,\n\n\t\tinterpolate_: function( i1, t0, t, t1 ) {\n\n\t\t\tvar result = this.resultBuffer,\n\t\t\t\tvalues = this.sampleValues,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toffset = i1 * stride,\n\n\t\t\t\talpha = ( t - t0 ) / ( t1 - t0 );\n\n\t\t\tfor ( var end = offset + stride; offset !== end; offset += 4 ) {\n\n\t\t\t\tQuaternion.slerpFlat( result, 0,\n\t\t\t\t\t\tvalues, offset - stride, values, offset, alpha );\n\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of quaternion keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction QuaternionKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tQuaternionKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: QuaternionKeyframeTrack,\n\n\t\tValueTypeName: 'quaternion',\n\n\t\t// ValueBufferType is inherited\n\n\t\tDefaultInterpolation: InterpolateLinear,\n\n\t\tInterpolantFactoryMethodLinear: function( result ) {\n\n\t\t\treturn new QuaternionLinearInterpolant(\n\t\t\t\t\tthis.times, this.values, this.getValueSize(), result );\n\n\t\t},\n\n\t\tInterpolantFactoryMethodSmooth: undefined // not yet implemented\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of numeric keyframe values.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction NumberKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tNumberKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: NumberKeyframeTrack,\n\n\t\tValueTypeName: 'number'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\t} );\n\n\t/**\n\t *\n\t * A Track that interpolates Strings\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction StringKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tStringKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: StringKeyframeTrack,\n\n\t\tValueTypeName: 'string',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of Boolean keyframe values.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction BooleanKeyframeTrack( name, times, values ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values );\n\n\t}\n\n\tBooleanKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: BooleanKeyframeTrack,\n\n\t\tValueTypeName: 'bool',\n\t\tValueBufferType: Array,\n\n\t\tDefaultInterpolation: InterpolateDiscrete,\n\n\t\tInterpolantFactoryMethodLinear: undefined,\n\t\tInterpolantFactoryMethodSmooth: undefined\n\n\t\t// Note: Actually this track could have a optimized / compressed\n\t\t// representation of a single value and a custom interpolant that\n\t\t// computes \"firstValue ^ isOdd( index )\".\n\n\t} );\n\n\t/**\n\t *\n\t * A Track of keyframe values that represent color.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction ColorKeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.call( this, name, times, values, interpolation );\n\n\t}\n\n\tColorKeyframeTrack.prototype =\n\t\t\tObject.assign( Object.create( KeyframeTrackPrototype ), {\n\n\t\tconstructor: ColorKeyframeTrack,\n\n\t\tValueTypeName: 'color'\n\n\t\t// ValueBufferType is inherited\n\n\t\t// DefaultInterpolation is inherited\n\n\n\t\t// Note: Very basic implementation and nothing special yet.\n\t\t// However, this is the place for color space parameterization.\n\n\t} );\n\n\t/**\n\t *\n\t * A timed sequence of keyframes for a specific property.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction KeyframeTrack( name, times, values, interpolation ) {\n\n\t\tKeyframeTrackConstructor.apply( this, arguments );\n\n\t}\n\n\tKeyframeTrack.prototype = KeyframeTrackPrototype;\n\tKeyframeTrackPrototype.constructor = KeyframeTrack;\n\n\t// Static methods:\n\n\tObject.assign( KeyframeTrack, {\n\n\t\t// Serialization (in static context, because of constructor invocation\n\t\t// and automatic invocation of .toJSON):\n\n\t\tparse: function( json ) {\n\n\t\t\tif( json.type === undefined ) {\n\n\t\t\t\tthrow new Error( \"track type undefined, can not parse\" );\n\n\t\t\t}\n\n\t\t\tvar trackType = KeyframeTrack._getTrackTypeForValueTypeName( json.type );\n\n\t\t\tif ( json.times === undefined ) {\n\n\t\t\t\tvar times = [], values = [];\n\n\t\t\t\tAnimationUtils.flattenJSON( json.keys, times, values, 'value' );\n\n\t\t\t\tjson.times = times;\n\t\t\t\tjson.values = values;\n\n\t\t\t}\n\n\t\t\t// derived classes can define a static parse method\n\t\t\tif ( trackType.parse !== undefined ) {\n\n\t\t\t\treturn trackType.parse( json );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we asssume a constructor compatible with the base\n\t\t\t\treturn new trackType(\n\t\t\t\t\t\tjson.name, json.times, json.values, json.interpolation );\n\n\t\t\t}\n\n\t\t},\n\n\t\ttoJSON: function( track ) {\n\n\t\t\tvar trackType = track.constructor;\n\n\t\t\tvar json;\n\n\t\t\t// derived classes can define a static toJSON method\n\t\t\tif ( trackType.toJSON !== undefined ) {\n\n\t\t\t\tjson = trackType.toJSON( track );\n\n\t\t\t} else {\n\n\t\t\t\t// by default, we assume the data can be serialized as-is\n\t\t\t\tjson = {\n\n\t\t\t\t\t'name': track.name,\n\t\t\t\t\t'times': AnimationUtils.convertArray( track.times, Array ),\n\t\t\t\t\t'values': AnimationUtils.convertArray( track.values, Array )\n\n\t\t\t\t};\n\n\t\t\t\tvar interpolation = track.getInterpolation();\n\n\t\t\t\tif ( interpolation !== track.DefaultInterpolation ) {\n\n\t\t\t\t\tjson.interpolation = interpolation;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tjson.type = track.ValueTypeName; // mandatory\n\n\t\t\treturn json;\n\n\t\t},\n\n\t\t_getTrackTypeForValueTypeName: function( typeName ) {\n\n\t\t\tswitch( typeName.toLowerCase() ) {\n\n\t\t\t\tcase \"scalar\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"number\":\n\t\t\t\tcase \"integer\":\n\n\t\t\t\t\treturn NumberKeyframeTrack;\n\n\t\t\t\tcase \"vector\":\n\t\t\t\tcase \"vector2\":\n\t\t\t\tcase \"vector3\":\n\t\t\t\tcase \"vector4\":\n\n\t\t\t\t\treturn VectorKeyframeTrack;\n\n\t\t\t\tcase \"color\":\n\n\t\t\t\t\treturn ColorKeyframeTrack;\n\n\t\t\t\tcase \"quaternion\":\n\n\t\t\t\t\treturn QuaternionKeyframeTrack;\n\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"boolean\":\n\n\t\t\t\t\treturn BooleanKeyframeTrack;\n\n\t\t\t\tcase \"string\":\n\n\t\t\t\t\treturn StringKeyframeTrack;\n\n\t\t\t}\n\n\t\t\tthrow new Error( \"Unsupported typeName: \" + typeName );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Reusable set of Tracks that represent an animation.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t */\n\n\tfunction AnimationClip( name, duration, tracks ) {\n\n\t\tthis.name = name;\n\t\tthis.tracks = tracks;\n\t\tthis.duration = ( duration !== undefined ) ? duration : -1;\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// this means it should figure out its duration by scanning the tracks\n\t\tif ( this.duration < 0 ) {\n\n\t\t\tthis.resetDuration();\n\n\t\t}\n\n\t\tthis.optimize();\n\n\t}\n\n\tAnimationClip.prototype = {\n\n\t\tconstructor: AnimationClip,\n\n\t\tresetDuration: function() {\n\n\t\t\tvar tracks = this.tracks,\n\t\t\t\tduration = 0;\n\n\t\t\tfor ( var i = 0, n = tracks.length; i !== n; ++ i ) {\n\n\t\t\t\tvar track = this.tracks[ i ];\n\n\t\t\t\tduration = Math.max( duration, track.times[ track.times.length - 1 ] );\n\n\t\t\t}\n\n\t\t\tthis.duration = duration;\n\n\t\t},\n\n\t\ttrim: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].trim( 0, this.duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\toptimize: function() {\n\n\t\t\tfor ( var i = 0; i < this.tracks.length; i ++ ) {\n\n\t\t\t\tthis.tracks[ i ].optimize();\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t// Static methods:\n\n\tObject.assign( AnimationClip, {\n\n\t\tparse: function( json ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tjsonTracks = json.tracks,\n\t\t\t\tframeTime = 1.0 / ( json.fps || 1.0 );\n\n\t\t\tfor ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) );\n\n\t\t\t}\n\n\t\t\treturn new AnimationClip( json.name, json.duration, tracks );\n\n\t\t},\n\n\n\t\ttoJSON: function( clip ) {\n\n\t\t\tvar tracks = [],\n\t\t\t\tclipTracks = clip.tracks;\n\n\t\t\tvar json = {\n\n\t\t\t\t'name': clip.name,\n\t\t\t\t'duration': clip.duration,\n\t\t\t\t'tracks': tracks\n\n\t\t\t};\n\n\t\t\tfor ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {\n\n\t\t\t\ttracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn json;\n\n\t\t},\n\n\n\t\tCreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) {\n\n\t\t\tvar numMorphTargets = morphTargetSequence.length;\n\t\t\tvar tracks = [];\n\n\t\t\tfor ( var i = 0; i < numMorphTargets; i ++ ) {\n\n\t\t\t\tvar times = [];\n\t\t\t\tvar values = [];\n\n\t\t\t\ttimes.push(\n\t\t\t\t\t\t( i + numMorphTargets - 1 ) % numMorphTargets,\n\t\t\t\t\t\ti,\n\t\t\t\t\t\t( i + 1 ) % numMorphTargets );\n\n\t\t\t\tvalues.push( 0, 1, 0 );\n\n\t\t\t\tvar order = AnimationUtils.getKeyframeOrder( times );\n\t\t\t\ttimes = AnimationUtils.sortedArray( times, 1, order );\n\t\t\t\tvalues = AnimationUtils.sortedArray( values, 1, order );\n\n\t\t\t\t// if there is a key at the first frame, duplicate it as the\n\t\t\t\t// last frame as well for perfect loop.\n\t\t\t\tif ( ! noLoop && times[ 0 ] === 0 ) {\n\n\t\t\t\t\ttimes.push( numMorphTargets );\n\t\t\t\t\tvalues.push( values[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\ttracks.push(\n\t\t\t\t\t\tnew NumberKeyframeTrack(\n\t\t\t\t\t\t\t'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',\n\t\t\t\t\t\t\ttimes, values\n\t\t\t\t\t\t).scale( 1.0 / fps ) );\n\t\t\t}\n\n\t\t\treturn new AnimationClip( name, -1, tracks );\n\n\t\t},\n\n\t\tfindByName: function( objectOrClipArray, name ) {\n\n\t\t\tvar clipArray = objectOrClipArray;\n\n\t\t\tif ( ! Array.isArray( objectOrClipArray ) ) {\n\n\t\t\t\tvar o = objectOrClipArray;\n\t\t\t\tclipArray = o.geometry && o.geometry.animations || o.animations;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < clipArray.length; i ++ ) {\n\n\t\t\t\tif ( clipArray[ i ].name === name ) {\n\n\t\t\t\t\treturn clipArray[ i ];\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\tCreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) {\n\n\t\t\tvar animationToMorphTargets = {};\n\n\t\t\t// tested with https://regex101.com/ on trick sequences\n\t\t\t// such flamingo_flyA_003, flamingo_run1_003, crdeath0059\n\t\t\tvar pattern = /^([\\w-]*?)([\\d]+)$/;\n\n\t\t\t// sort morph target names into animation groups based\n\t\t\t// patterns like Walk_001, Walk_002, Run_001, Run_002\n\t\t\tfor ( var i = 0, il = morphTargets.length; i < il; i ++ ) {\n\n\t\t\t\tvar morphTarget = morphTargets[ i ];\n\t\t\t\tvar parts = morphTarget.name.match( pattern );\n\n\t\t\t\tif ( parts && parts.length > 1 ) {\n\n\t\t\t\t\tvar name = parts[ 1 ];\n\n\t\t\t\t\tvar animationMorphTargets = animationToMorphTargets[ name ];\n\t\t\t\t\tif ( ! animationMorphTargets ) {\n\n\t\t\t\t\t\tanimationToMorphTargets[ name ] = animationMorphTargets = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tanimationMorphTargets.push( morphTarget );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar clips = [];\n\n\t\t\tfor ( var name in animationToMorphTargets ) {\n\n\t\t\t\tclips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );\n\n\t\t\t}\n\n\t\t\treturn clips;\n\n\t\t},\n\n\t\t// parse the animation.hierarchy format\n\t\tparseAnimation: function( animation, bones ) {\n\n\t\t\tif ( ! animation ) {\n\n\t\t\t\tconsole.error( \" no animation in JSONLoader data\" );\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar addNonemptyTrack = function(\n\t\t\t\t\ttrackType, trackName, animationKeys, propertyName, destTracks ) {\n\n\t\t\t\t// only return track if there are actually keys.\n\t\t\t\tif ( animationKeys.length !== 0 ) {\n\n\t\t\t\t\tvar times = [];\n\t\t\t\t\tvar values = [];\n\n\t\t\t\t\tAnimationUtils.flattenJSON(\n\t\t\t\t\t\t\tanimationKeys, times, values, propertyName );\n\n\t\t\t\t\t// empty keys are filtered out, so check again\n\t\t\t\t\tif ( times.length !== 0 ) {\n\n\t\t\t\t\t\tdestTracks.push( new trackType( trackName, times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tvar tracks = [];\n\n\t\t\tvar clipName = animation.name || 'default';\n\t\t\t// automatic length determination in AnimationClip.\n\t\t\tvar duration = animation.length || -1;\n\t\t\tvar fps = animation.fps || 30;\n\n\t\t\tvar hierarchyTracks = animation.hierarchy || [];\n\n\t\t\tfor ( var h = 0; h < hierarchyTracks.length; h ++ ) {\n\n\t\t\t\tvar animationKeys = hierarchyTracks[ h ].keys;\n\n\t\t\t\t// skip empty tracks\n\t\t\t\tif ( ! animationKeys || animationKeys.length === 0 ) continue;\n\n\t\t\t\t// process morph targets in a way exactly compatible\n\t\t\t\t// with AnimationHandler.init( animation )\n\t\t\t\tif ( animationKeys[0].morphTargets ) {\n\n\t\t\t\t\t// figure out all morph targets used in this track\n\t\t\t\t\tvar morphTargetNames = {};\n\t\t\t\t\tfor ( var k = 0; k < animationKeys.length; k ++ ) {\n\n\t\t\t\t\t\tif ( animationKeys[k].morphTargets ) {\n\n\t\t\t\t\t\t\tfor ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) {\n\n\t\t\t\t\t\t\t\tmorphTargetNames[ animationKeys[k].morphTargets[m] ] = -1;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// create a track for each morph target with all zero\n\t\t\t\t\t// morphTargetInfluences except for the keys in which\n\t\t\t\t\t// the morphTarget is named.\n\t\t\t\t\tfor ( var morphTargetName in morphTargetNames ) {\n\n\t\t\t\t\t\tvar times = [];\n\t\t\t\t\t\tvar values = [];\n\n\t\t\t\t\t\tfor ( var m = 0; m !== animationKeys[k].morphTargets.length; ++ m ) {\n\n\t\t\t\t\t\t\tvar animationKey = animationKeys[k];\n\n\t\t\t\t\t\t\ttimes.push( animationKey.time );\n\t\t\t\t\t\t\tvalues.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracks.push( new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tduration = morphTargetNames.length * ( fps || 1.0 );\n\n\t\t\t\t} else {\n\t\t\t\t\t// ...assume skeletal animation\n\n\t\t\t\t\tvar boneName = '.bones[' + bones[ h ].name + ']';\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.position',\n\t\t\t\t\t\t\tanimationKeys, 'pos', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tQuaternionKeyframeTrack, boneName + '.quaternion',\n\t\t\t\t\t\t\tanimationKeys, 'rot', tracks );\n\n\t\t\t\t\taddNonemptyTrack(\n\t\t\t\t\t\t\tVectorKeyframeTrack, boneName + '.scale',\n\t\t\t\t\t\t\tanimationKeys, 'scl', tracks );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( tracks.length === 0 ) {\n\n\t\t\t\treturn null;\n\n\t\t\t}\n\n\t\t\tvar clip = new AnimationClip( clipName, duration, tracks );\n\n\t\t\treturn clip;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction MaterialLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.textures = {};\n\n\t}\n\n\tObject.assign( MaterialLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTextures: function ( value ) {\n\n\t\t\tthis.textures = value;\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar textures = this.textures;\n\n\t\t\tfunction getTexture( name ) {\n\n\t\t\t\tif ( textures[ name ] === undefined ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.MaterialLoader: Undefined texture', name );\n\n\t\t\t\t}\n\n\t\t\t\treturn textures[ name ];\n\n\t\t\t}\n\n\t\t\tvar material = new Materials[ json.type ]();\n\n\t\t\tif ( json.uuid !== undefined ) material.uuid = json.uuid;\n\t\t\tif ( json.name !== undefined ) material.name = json.name;\n\t\t\tif ( json.color !== undefined ) material.color.setHex( json.color );\n\t\t\tif ( json.roughness !== undefined ) material.roughness = json.roughness;\n\t\t\tif ( json.metalness !== undefined ) material.metalness = json.metalness;\n\t\t\tif ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );\n\t\t\tif ( json.specular !== undefined ) material.specular.setHex( json.specular );\n\t\t\tif ( json.shininess !== undefined ) material.shininess = json.shininess;\n\t\t\tif ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;\n\t\t\tif ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;\n\t\t\tif ( json.uniforms !== undefined ) material.uniforms = json.uniforms;\n\t\t\tif ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;\n\t\t\tif ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;\n\t\t\tif ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;\n\t\t\tif ( json.fog !== undefined ) material.fog = json.fog;\n\t\t\tif ( json.shading !== undefined ) material.shading = json.shading;\n\t\t\tif ( json.blending !== undefined ) material.blending = json.blending;\n\t\t\tif ( json.side !== undefined ) material.side = json.side;\n\t\t\tif ( json.opacity !== undefined ) material.opacity = json.opacity;\n\t\t\tif ( json.transparent !== undefined ) material.transparent = json.transparent;\n\t\t\tif ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;\n\t\t\tif ( json.depthTest !== undefined ) material.depthTest = json.depthTest;\n\t\t\tif ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;\n\t\t\tif ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;\n\t\t\tif ( json.wireframe !== undefined ) material.wireframe = json.wireframe;\n\t\t\tif ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;\n\t\t\tif ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;\n\t\t\tif ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;\n\t\t\tif ( json.skinning !== undefined ) material.skinning = json.skinning;\n\t\t\tif ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;\n\n\t\t\t// for PointsMaterial\n\n\t\t\tif ( json.size !== undefined ) material.size = json.size;\n\t\t\tif ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;\n\n\t\t\t// maps\n\n\t\t\tif ( json.map !== undefined ) material.map = getTexture( json.map );\n\n\t\t\tif ( json.alphaMap !== undefined ) {\n\n\t\t\t\tmaterial.alphaMap = getTexture( json.alphaMap );\n\t\t\t\tmaterial.transparent = true;\n\n\t\t\t}\n\n\t\t\tif ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );\n\t\t\tif ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;\n\n\t\t\tif ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );\n\t\t\tif ( json.normalScale !== undefined ) {\n\n\t\t\t\tvar normalScale = json.normalScale;\n\n\t\t\t\tif ( Array.isArray( normalScale ) === false ) {\n\n\t\t\t\t\t// Blender exporter used to export a scalar. See #7459\n\n\t\t\t\t\tnormalScale = [ normalScale, normalScale ];\n\n\t\t\t\t}\n\n\t\t\t\tmaterial.normalScale = new Vector2().fromArray( normalScale );\n\n\t\t\t}\n\n\t\t\tif ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );\n\t\t\tif ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;\n\t\t\tif ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;\n\n\t\t\tif ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );\n\t\t\tif ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );\n\n\t\t\tif ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );\n\t\t\tif ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;\n\n\t\t\tif ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );\n\n\t\t\tif ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );\n\n\t\t\tif ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;\n\n\t\t\tif ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );\n\t\t\tif ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;\n\n\t\t\tif ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );\n\t\t\tif ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;\n\n\t\t\tif ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );\n\n\t\t\t// MultiMaterial\n\n\t\t\tif ( json.materials !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.materials.length; i < l; i ++ ) {\n\n\t\t\t\t\tmaterial.materials.push( this.parse( json.materials[ i ] ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn material;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BufferGeometryLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( BufferGeometryLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tonLoad( scope.parse( JSON.parse( text ) ) );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\tvar geometry = new BufferGeometry();\n\n\t\t\tvar index = json.data.index;\n\n\t\t\tvar TYPED_ARRAYS = {\n\t\t\t\t'Int8Array': Int8Array,\n\t\t\t\t'Uint8Array': Uint8Array,\n\t\t\t\t'Uint8ClampedArray': Uint8ClampedArray,\n\t\t\t\t'Int16Array': Int16Array,\n\t\t\t\t'Uint16Array': Uint16Array,\n\t\t\t\t'Int32Array': Int32Array,\n\t\t\t\t'Uint32Array': Uint32Array,\n\t\t\t\t'Float32Array': Float32Array,\n\t\t\t\t'Float64Array': Float64Array\n\t\t\t};\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ index.type ]( index.array );\n\t\t\t\tgeometry.setIndex( new BufferAttribute( typedArray, 1 ) );\n\n\t\t\t}\n\n\t\t\tvar attributes = json.data.attributes;\n\n\t\t\tfor ( var key in attributes ) {\n\n\t\t\t\tvar attribute = attributes[ key ];\n\t\t\t\tvar typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array );\n\n\t\t\t\tgeometry.addAttribute( key, new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) );\n\n\t\t\t}\n\n\t\t\tvar groups = json.data.groups || json.data.drawcalls || json.data.offsets;\n\n\t\t\tif ( groups !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, n = groups.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar group = groups[ i ];\n\n\t\t\t\t\tgeometry.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar boundingSphere = json.data.boundingSphere;\n\n\t\t\tif ( boundingSphere !== undefined ) {\n\n\t\t\t\tvar center = new Vector3();\n\n\t\t\t\tif ( boundingSphere.center !== undefined ) {\n\n\t\t\t\t\tcenter.fromArray( boundingSphere.center );\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.boundingSphere = new Sphere( center, boundingSphere.radius );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Loader() {\n\n\t\tthis.onLoadStart = function () {};\n\t\tthis.onLoadProgress = function () {};\n\t\tthis.onLoadComplete = function () {};\n\n\t}\n\n\tLoader.prototype = {\n\n\t\tconstructor: Loader,\n\n\t\tcrossOrigin: undefined,\n\n\t\textractUrlBase: function ( url ) {\n\n\t\t\tvar parts = url.split( '/' );\n\n\t\t\tif ( parts.length === 1 ) return './';\n\n\t\t\tparts.pop();\n\n\t\t\treturn parts.join( '/' ) + '/';\n\n\t\t},\n\n\t\tinitMaterials: function ( materials, texturePath, crossOrigin ) {\n\n\t\t\tvar array = [];\n\n\t\t\tfor ( var i = 0; i < materials.length; ++ i ) {\n\n\t\t\t\tarray[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin );\n\n\t\t\t}\n\n\t\t\treturn array;\n\n\t\t},\n\n\t\tcreateMaterial: ( function () {\n\n\t\t\tvar BlendingMode = {\n\t\t\t\tNoBlending: NoBlending,\n\t\t\t\tNormalBlending: NormalBlending,\n\t\t\t\tAdditiveBlending: AdditiveBlending,\n\t\t\t\tSubtractiveBlending: SubtractiveBlending,\n\t\t\t\tMultiplyBlending: MultiplyBlending,\n\t\t\t\tCustomBlending: CustomBlending\n\t\t\t};\n\n\t\t\tvar color, textureLoader, materialLoader;\n\n\t\t\treturn function createMaterial( m, texturePath, crossOrigin ) {\n\n\t\t\t\tif ( color === undefined ) color = new Color();\n\t\t\t\tif ( textureLoader === undefined ) textureLoader = new TextureLoader();\n\t\t\t\tif ( materialLoader === undefined ) materialLoader = new MaterialLoader();\n\n\t\t\t\t// convert from old material format\n\n\t\t\t\tvar textures = {};\n\n\t\t\t\tfunction loadTexture( path, repeat, offset, wrap, anisotropy ) {\n\n\t\t\t\t\tvar fullPath = texturePath + path;\n\t\t\t\t\tvar loader = Loader.Handlers.get( fullPath );\n\n\t\t\t\t\tvar texture;\n\n\t\t\t\t\tif ( loader !== null ) {\n\n\t\t\t\t\t\ttexture = loader.load( fullPath );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\ttextureLoader.setCrossOrigin( crossOrigin );\n\t\t\t\t\t\ttexture = textureLoader.load( fullPath );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( repeat !== undefined ) {\n\n\t\t\t\t\t\ttexture.repeat.fromArray( repeat );\n\n\t\t\t\t\t\tif ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( offset !== undefined ) {\n\n\t\t\t\t\t\ttexture.offset.fromArray( offset );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( wrap !== undefined ) {\n\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping;\n\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping;\n\t\t\t\t\t\tif ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( anisotropy !== undefined ) {\n\n\t\t\t\t\t\ttexture.anisotropy = anisotropy;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar uuid = _Math.generateUUID();\n\n\t\t\t\t\ttextures[ uuid ] = texture;\n\n\t\t\t\t\treturn uuid;\n\n\t\t\t\t}\n\n\t\t\t\t//\n\n\t\t\t\tvar json = {\n\t\t\t\t\tuuid: _Math.generateUUID(),\n\t\t\t\t\ttype: 'MeshLambertMaterial'\n\t\t\t\t};\n\n\t\t\t\tfor ( var name in m ) {\n\n\t\t\t\t\tvar value = m[ name ];\n\n\t\t\t\t\tswitch ( name ) {\n\n\t\t\t\t\t\tcase 'DbgColor':\n\t\t\t\t\t\tcase 'DbgIndex':\n\t\t\t\t\t\tcase 'opticalDensity':\n\t\t\t\t\t\tcase 'illumination':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'DbgName':\n\t\t\t\t\t\t\tjson.name = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'blending':\n\t\t\t\t\t\t\tjson.blending = BlendingMode[ value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorAmbient':\n\t\t\t\t\t\tcase 'mapAmbient':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorDiffuse':\n\t\t\t\t\t\t\tjson.color = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorSpecular':\n\t\t\t\t\t\t\tjson.specular = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'colorEmissive':\n\t\t\t\t\t\t\tjson.emissive = color.fromArray( value ).getHex();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'specularCoef':\n\t\t\t\t\t\t\tjson.shininess = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'shading':\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';\n\t\t\t\t\t\t\tif ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuse':\n\t\t\t\t\t\t\tjson.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapDiffuseRepeat':\n\t\t\t\t\t\tcase 'mapDiffuseOffset':\n\t\t\t\t\t\tcase 'mapDiffuseWrap':\n\t\t\t\t\t\tcase 'mapDiffuseAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissive':\n\t\t\t\t\t\t\tjson.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapEmissiveRepeat':\n\t\t\t\t\t\tcase 'mapEmissiveOffset':\n\t\t\t\t\t\tcase 'mapEmissiveWrap':\n\t\t\t\t\t\tcase 'mapEmissiveAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLight':\n\t\t\t\t\t\t\tjson.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapLightRepeat':\n\t\t\t\t\t\tcase 'mapLightOffset':\n\t\t\t\t\t\tcase 'mapLightWrap':\n\t\t\t\t\t\tcase 'mapLightAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAO':\n\t\t\t\t\t\t\tjson.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAORepeat':\n\t\t\t\t\t\tcase 'mapAOOffset':\n\t\t\t\t\t\tcase 'mapAOWrap':\n\t\t\t\t\t\tcase 'mapAOAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBump':\n\t\t\t\t\t\t\tjson.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpScale':\n\t\t\t\t\t\t\tjson.bumpScale = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapBumpRepeat':\n\t\t\t\t\t\tcase 'mapBumpOffset':\n\t\t\t\t\t\tcase 'mapBumpWrap':\n\t\t\t\t\t\tcase 'mapBumpAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormal':\n\t\t\t\t\t\t\tjson.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalFactor':\n\t\t\t\t\t\t\tjson.normalScale = [ value, value ];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapNormalRepeat':\n\t\t\t\t\t\tcase 'mapNormalOffset':\n\t\t\t\t\t\tcase 'mapNormalWrap':\n\t\t\t\t\t\tcase 'mapNormalAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecular':\n\t\t\t\t\t\t\tjson.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapSpecularRepeat':\n\t\t\t\t\t\tcase 'mapSpecularOffset':\n\t\t\t\t\t\tcase 'mapSpecularWrap':\n\t\t\t\t\t\tcase 'mapSpecularAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalness':\n\t\t\t\t\t\t\tjson.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapMetalnessRepeat':\n\t\t\t\t\t\tcase 'mapMetalnessOffset':\n\t\t\t\t\t\tcase 'mapMetalnessWrap':\n\t\t\t\t\t\tcase 'mapMetalnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughness':\n\t\t\t\t\t\t\tjson.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapRoughnessRepeat':\n\t\t\t\t\t\tcase 'mapRoughnessOffset':\n\t\t\t\t\t\tcase 'mapRoughnessWrap':\n\t\t\t\t\t\tcase 'mapRoughnessAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlpha':\n\t\t\t\t\t\t\tjson.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'mapAlphaRepeat':\n\t\t\t\t\t\tcase 'mapAlphaOffset':\n\t\t\t\t\t\tcase 'mapAlphaWrap':\n\t\t\t\t\t\tcase 'mapAlphaAnisotropy':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'flipSided':\n\t\t\t\t\t\t\tjson.side = BackSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'doubleSided':\n\t\t\t\t\t\t\tjson.side = DoubleSide;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'transparency':\n\t\t\t\t\t\t\tconsole.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' );\n\t\t\t\t\t\t\tjson.opacity = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'depthTest':\n\t\t\t\t\t\tcase 'depthWrite':\n\t\t\t\t\t\tcase 'colorWrite':\n\t\t\t\t\t\tcase 'opacity':\n\t\t\t\t\t\tcase 'reflectivity':\n\t\t\t\t\t\tcase 'transparent':\n\t\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tcase 'wireframe':\n\t\t\t\t\t\t\tjson[ name ] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'vertexColors':\n\t\t\t\t\t\t\tif ( value === true ) json.vertexColors = VertexColors;\n\t\t\t\t\t\t\tif ( value === 'face' ) json.vertexColors = FaceColors;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tconsole.error( 'THREE.Loader.createMaterial: Unsupported', name, value );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.type === 'MeshBasicMaterial' ) delete json.emissive;\n\t\t\t\tif ( json.type !== 'MeshPhongMaterial' ) delete json.specular;\n\n\t\t\t\tif ( json.opacity < 1 ) json.transparent = true;\n\n\t\t\t\tmaterialLoader.setTextures( textures );\n\n\t\t\t\treturn materialLoader.parse( json );\n\n\t\t\t};\n\n\t\t} )()\n\n\t};\n\n\tLoader.Handlers = {\n\n\t\thandlers: [],\n\n\t\tadd: function ( regex, loader ) {\n\n\t\t\tthis.handlers.push( regex, loader );\n\n\t\t},\n\n\t\tget: function ( file ) {\n\n\t\t\tvar handlers = this.handlers;\n\n\t\t\tfor ( var i = 0, l = handlers.length; i < l; i += 2 ) {\n\n\t\t\t\tvar regex = handlers[ i ];\n\t\t\t\tvar loader = handlers[ i + 1 ];\n\n\t\t\t\tif ( regex.test( file ) ) {\n\n\t\t\t\t\treturn loader;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction JSONLoader( manager ) {\n\n\t\tif ( typeof manager === 'boolean' ) {\n\n\t\t\tconsole.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );\n\t\t\tmanager = undefined;\n\n\t\t}\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t\tthis.withCredentials = false;\n\n\t}\n\n\tObject.assign( JSONLoader.prototype, {\n\n\t\tload: function( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar texturePath = this.texturePath && ( typeof this.texturePath === \"string\" ) ? this.texturePath : Loader.prototype.extractUrlBase( url );\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = JSON.parse( text );\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata !== undefined ) {\n\n\t\t\t\t\tvar type = metadata.type;\n\n\t\t\t\t\tif ( type !== undefined ) {\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'object' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type.toLowerCase() === 'scene' ) {\n\n\t\t\t\t\t\t\tconsole.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.SceneLoader instead.' );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tvar object = scope.parse( json, texturePath );\n\t\t\t\tonLoad( object.geometry, object.materials );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tparse: function ( json, texturePath ) {\n\n\t\t\tvar geometry = new Geometry(),\n\t\t\tscale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;\n\n\t\t\tparseModel( scale );\n\n\t\t\tparseSkin();\n\t\t\tparseMorphing( scale );\n\t\t\tparseAnimations();\n\n\t\t\tgeometry.computeFaceNormals();\n\t\t\tgeometry.computeBoundingSphere();\n\n\t\t\tfunction parseModel( scale ) {\n\n\t\t\t\tfunction isBitSet( value, position ) {\n\n\t\t\t\t\treturn value & ( 1 << position );\n\n\t\t\t\t}\n\n\t\t\t\tvar i, j, fi,\n\n\t\t\t\toffset, zLength,\n\n\t\t\tcolorIndex, normalIndex, uvIndex, materialIndex,\n\n\t\t\t\ttype,\n\t\t\t\tisQuad,\n\t\t\t\thasMaterial,\n\t\t\t\thasFaceVertexUv,\n\t\t\t\thasFaceNormal, hasFaceVertexNormal,\n\t\t\t\thasFaceColor, hasFaceVertexColor,\n\n\t\t\tvertex, face, faceA, faceB, hex, normal,\n\n\t\t\t\tuvLayer, uv, u, v,\n\n\t\t\t\tfaces = json.faces,\n\t\t\t\tvertices = json.vertices,\n\t\t\t\tnormals = json.normals,\n\t\t\t\tcolors = json.colors,\n\n\t\t\t\tnUvLayers = 0;\n\n\t\t\t\tif ( json.uvs !== undefined ) {\n\n\t\t\t\t\t// disregard empty arrays\n\n\t\t\t\t\tfor ( i = 0; i < json.uvs.length; i ++ ) {\n\n\t\t\t\t\t\tif ( json.uvs[ i ].length ) nUvLayers ++;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\tgeometry.faceVertexUvs[ i ] = [];\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = vertices.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\tvertex = new Vector3();\n\n\t\t\t\t\tvertex.x = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.y = vertices[ offset ++ ] * scale;\n\t\t\t\t\tvertex.z = vertices[ offset ++ ] * scale;\n\n\t\t\t\t\tgeometry.vertices.push( vertex );\n\n\t\t\t\t}\n\n\t\t\t\toffset = 0;\n\t\t\t\tzLength = faces.length;\n\n\t\t\t\twhile ( offset < zLength ) {\n\n\t\t\t\t\ttype = faces[ offset ++ ];\n\n\n\t\t\t\t\tisQuad = isBitSet( type, 0 );\n\t\t\t\t\thasMaterial = isBitSet( type, 1 );\n\t\t\t\t\thasFaceVertexUv = isBitSet( type, 3 );\n\t\t\t\t\thasFaceNormal = isBitSet( type, 4 );\n\t\t\t\t\thasFaceVertexNormal = isBitSet( type, 5 );\n\t\t\t\t\thasFaceColor\t = isBitSet( type, 6 );\n\t\t\t\t\thasFaceVertexColor = isBitSet( type, 7 );\n\n\t\t\t\t\t// console.log(\"type\", type, \"bits\", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);\n\n\t\t\t\t\tif ( isQuad ) {\n\n\t\t\t\t\t\tfaceA = new Face3();\n\t\t\t\t\t\tfaceA.a = faces[ offset ];\n\t\t\t\t\t\tfaceA.b = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceA.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\tfaceB = new Face3();\n\t\t\t\t\t\tfaceB.a = faces[ offset + 1 ];\n\t\t\t\t\t\tfaceB.b = faces[ offset + 2 ];\n\t\t\t\t\t\tfaceB.c = faces[ offset + 3 ];\n\n\t\t\t\t\t\toffset += 4;\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tfaceA.materialIndex = materialIndex;\n\t\t\t\t\t\t\tfaceB.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi + 1 ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 4; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tif ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );\n\t\t\t\t\t\t\t\t\tif ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tfaceA.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfaceB.normal.copy( faceA.normal );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexNormals.push( normal );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\tfaceA.color.setHex( hex );\n\t\t\t\t\t\t\tfaceB.color.setHex( hex );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 4; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\thex = colors[ colorIndex ];\n\n\t\t\t\t\t\t\t\tif ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );\n\t\t\t\t\t\t\t\tif ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( faceA );\n\t\t\t\t\t\tgeometry.faces.push( faceB );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tface = new Face3();\n\t\t\t\t\t\tface.a = faces[ offset ++ ];\n\t\t\t\t\t\tface.b = faces[ offset ++ ];\n\t\t\t\t\t\tface.c = faces[ offset ++ ];\n\n\t\t\t\t\t\tif ( hasMaterial ) {\n\n\t\t\t\t\t\t\tmaterialIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.materialIndex = materialIndex;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// to get face <=> uv index correspondence\n\n\t\t\t\t\t\tfi = geometry.faces.length;\n\n\t\t\t\t\t\tif ( hasFaceVertexUv ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < nUvLayers; i ++ ) {\n\n\t\t\t\t\t\t\t\tuvLayer = json.uvs[ i ];\n\n\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ] = [];\n\n\t\t\t\t\t\t\t\tfor ( j = 0; j < 3; j ++ ) {\n\n\t\t\t\t\t\t\t\t\tuvIndex = faces[ offset ++ ];\n\n\t\t\t\t\t\t\t\t\tu = uvLayer[ uvIndex * 2 ];\n\t\t\t\t\t\t\t\t\tv = uvLayer[ uvIndex * 2 + 1 ];\n\n\t\t\t\t\t\t\t\t\tuv = new Vector2( u, v );\n\n\t\t\t\t\t\t\t\t\tgeometry.faceVertexUvs[ i ][ fi ].push( uv );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceNormal ) {\n\n\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\tface.normal.set(\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( hasFaceVertexNormal ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tnormalIndex = faces[ offset ++ ] * 3;\n\n\t\t\t\t\t\t\t\tnormal = new Vector3(\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ++ ],\n\t\t\t\t\t\t\t\t\tnormals[ normalIndex ]\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tface.vertexNormals.push( normal );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceColor ) {\n\n\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\tface.color.setHex( colors[ colorIndex ] );\n\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\tif ( hasFaceVertexColor ) {\n\n\t\t\t\t\t\t\tfor ( i = 0; i < 3; i ++ ) {\n\n\t\t\t\t\t\t\t\tcolorIndex = faces[ offset ++ ];\n\t\t\t\t\t\t\t\tface.vertexColors.push( new Color( colors[ colorIndex ] ) );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tgeometry.faces.push( face );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseSkin() {\n\n\t\t\t\tvar influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;\n\n\t\t\t\tif ( json.skinWeights ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar x = json.skinWeights[ i ];\n\t\t\t\t\t\tvar y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;\n\t\t\t\t\t\tvar z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;\n\t\t\t\t\t\tvar w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinWeights.push( new Vector4( x, y, z, w ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.skinIndices ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {\n\n\t\t\t\t\t\tvar a = json.skinIndices[ i ];\n\t\t\t\t\t\tvar b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;\n\t\t\t\t\t\tvar c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;\n\t\t\t\t\t\tvar d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;\n\n\t\t\t\t\t\tgeometry.skinIndices.push( new Vector4( a, b, c, d ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tgeometry.bones = json.bones;\n\n\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {\n\n\t\t\t\t\tconsole.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +\n\t\t\t\t\t\tgeometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseMorphing( scale ) {\n\n\t\t\t\tif ( json.morphTargets !== undefined ) {\n\n\t\t\t\t\tfor ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tgeometry.morphTargets[ i ] = {};\n\t\t\t\t\t\tgeometry.morphTargets[ i ].name = json.morphTargets[ i ].name;\n\t\t\t\t\t\tgeometry.morphTargets[ i ].vertices = [];\n\n\t\t\t\t\t\tvar dstVertices = geometry.morphTargets[ i ].vertices;\n\t\t\t\t\t\tvar srcVertices = json.morphTargets[ i ].vertices;\n\n\t\t\t\t\t\tfor ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {\n\n\t\t\t\t\t\t\tvar vertex = new Vector3();\n\t\t\t\t\t\t\tvertex.x = srcVertices[ v ] * scale;\n\t\t\t\t\t\t\tvertex.y = srcVertices[ v + 1 ] * scale;\n\t\t\t\t\t\t\tvertex.z = srcVertices[ v + 2 ] * scale;\n\n\t\t\t\t\t\t\tdstVertices.push( vertex );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.morphColors !== undefined && json.morphColors.length > 0 ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.JSONLoader: \"morphColors\" no longer supported. Using them as face colors.' );\n\n\t\t\t\t\tvar faces = geometry.faces;\n\t\t\t\t\tvar morphColors = json.morphColors[ 0 ].colors;\n\n\t\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\t\tfaces[ i ].color.fromArray( morphColors, i * 3 );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction parseAnimations() {\n\n\t\t\t\tvar outputAnimations = [];\n\n\t\t\t\t// parse old style Bone/Hierarchy animations\n\t\t\t\tvar animations = [];\n\n\t\t\t\tif ( json.animation !== undefined ) {\n\n\t\t\t\t\tanimations.push( json.animation );\n\n\t\t\t\t}\n\n\t\t\t\tif ( json.animations !== undefined ) {\n\n\t\t\t\t\tif ( json.animations.length ) {\n\n\t\t\t\t\t\tanimations = animations.concat( json.animations );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tanimations.push( json.animations );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var i = 0; i < animations.length; i ++ ) {\n\n\t\t\t\t\tvar clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );\n\t\t\t\t\tif ( clip ) outputAnimations.push( clip );\n\n\t\t\t\t}\n\n\t\t\t\t// parse implicit morph animations\n\t\t\t\tif ( geometry.morphTargets ) {\n\n\t\t\t\t\t// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.\n\t\t\t\t\tvar morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );\n\t\t\t\t\toutputAnimations = outputAnimations.concat( morphAnimationClips );\n\n\t\t\t\t}\n\n\t\t\t\tif ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;\n\n\t\t\t}\n\n\t\t\tif ( json.materials === undefined || json.materials.length === 0 ) {\n\n\t\t\t\treturn { geometry: geometry };\n\n\t\t\t} else {\n\n\t\t\t\tvar materials = Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );\n\n\t\t\t\treturn { geometry: geometry, materials: materials };\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction ObjectLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\t\tthis.texturePath = '';\n\n\t}\n\n\tObject.assign( ObjectLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tif ( this.texturePath === '' ) {\n\n\t\t\t\tthis.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );\n\n\t\t\t}\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( scope.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json = null;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( error ) {\n\n\t\t\t\t\tif ( onError !== undefined ) onError( error );\n\n\t\t\t\t\tconsole.error( 'THREE:ObjectLoader: Can\\'t parse ' + url + '.', error.message );\n\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tvar metadata = json.metadata;\n\n\t\t\t\tif ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {\n\n\t\t\t\t\tconsole.error( 'THREE.ObjectLoader: Can\\'t load ' + url + '. Use THREE.JSONLoader instead.' );\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tscope.parse( json, onLoad );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tsetTexturePath: function ( value ) {\n\n\t\t\tthis.texturePath = value;\n\n\t\t},\n\n\t\tsetCrossOrigin: function ( value ) {\n\n\t\t\tthis.crossOrigin = value;\n\n\t\t},\n\n\t\tparse: function ( json, onLoad ) {\n\n\t\t\tvar geometries = this.parseGeometries( json.geometries );\n\n\t\t\tvar images = this.parseImages( json.images, function () {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t} );\n\n\t\t\tvar textures = this.parseTextures( json.textures, images );\n\t\t\tvar materials = this.parseMaterials( json.materials, textures );\n\n\t\t\tvar object = this.parseObject( json.object, geometries, materials );\n\n\t\t\tif ( json.animations ) {\n\n\t\t\t\tobject.animations = this.parseAnimations( json.animations );\n\n\t\t\t}\n\n\t\t\tif ( json.images === undefined || json.images.length === 0 ) {\n\n\t\t\t\tif ( onLoad !== undefined ) onLoad( object );\n\n\t\t\t}\n\n\t\t\treturn object;\n\n\t\t},\n\n\t\tparseGeometries: function ( json ) {\n\n\t\t\tvar geometries = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar geometryLoader = new JSONLoader();\n\t\t\t\tvar bufferGeometryLoader = new BufferGeometryLoader();\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar geometry;\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\t\t\tcase 'PlaneBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BoxGeometry':\n\t\t\t\t\t\tcase 'BoxBufferGeometry':\n\t\t\t\t\t\tcase 'CubeGeometry': // backwards compatible\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.width,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.depth,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.depthSegments\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CircleGeometry':\n\t\t\t\t\t\tcase 'CircleBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\t\t\tcase 'CylinderBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radiusTop,\n\t\t\t\t\t\t\t\tdata.radiusBottom,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\t\tcase 'ConeBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.height,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.openEnded,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'SphereGeometry':\n\t\t\t\t\t\tcase 'SphereBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.widthSegments,\n\t\t\t\t\t\t\t\tdata.heightSegments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'DodecahedronGeometry':\n\t\t\t\t\t\tcase 'IcosahedronGeometry':\n\t\t\t\t\t\tcase 'OctahedronGeometry':\n\t\t\t\t\t\tcase 'TetrahedronGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.detail\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'RingGeometry':\n\t\t\t\t\t\tcase 'RingBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.innerRadius,\n\t\t\t\t\t\t\t\tdata.outerRadius,\n\t\t\t\t\t\t\t\tdata.thetaSegments,\n\t\t\t\t\t\t\t\tdata.phiSegments,\n\t\t\t\t\t\t\t\tdata.thetaStart,\n\t\t\t\t\t\t\t\tdata.thetaLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusGeometry':\n\t\t\t\t\t\tcase 'TorusBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.arc\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\t\t\tcase 'TorusKnotBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\t\t\tdata.tube,\n\t\t\t\t\t\t\t\tdata.tubularSegments,\n\t\t\t\t\t\t\t\tdata.radialSegments,\n\t\t\t\t\t\t\t\tdata.p,\n\t\t\t\t\t\t\t\tdata.q\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'LatheGeometry':\n\t\t\t\t\t\tcase 'LatheBufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = new Geometries[ data.type ](\n\t\t\t\t\t\t\t\tdata.points,\n\t\t\t\t\t\t\t\tdata.segments,\n\t\t\t\t\t\t\t\tdata.phiStart,\n\t\t\t\t\t\t\t\tdata.phiLength\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'BufferGeometry':\n\n\t\t\t\t\t\t\tgeometry = bufferGeometryLoader.parse( data );\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'Geometry':\n\n\t\t\t\t\t\t\tgeometry = geometryLoader.parse( data.data, this.texturePath ).geometry;\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Unsupported geometry type \"' + data.type + '\"' );\n\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tgeometry.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) geometry.name = data.name;\n\n\t\t\t\t\tgeometries[ data.uuid ] = geometry;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn geometries;\n\n\t\t},\n\n\t\tparseMaterials: function ( json, textures ) {\n\n\t\t\tvar materials = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tvar loader = new MaterialLoader();\n\t\t\t\tloader.setTextures( textures );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar material = loader.parse( json[ i ] );\n\t\t\t\t\tmaterials[ material.uuid ] = material;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn materials;\n\n\t\t},\n\n\t\tparseAnimations: function ( json ) {\n\n\t\t\tvar animations = [];\n\n\t\t\tfor ( var i = 0; i < json.length; i ++ ) {\n\n\t\t\t\tvar clip = AnimationClip.parse( json[ i ] );\n\n\t\t\t\tanimations.push( clip );\n\n\t\t\t}\n\n\t\t\treturn animations;\n\n\t\t},\n\n\t\tparseImages: function ( json, onLoad ) {\n\n\t\t\tvar scope = this;\n\t\t\tvar images = {};\n\n\t\t\tfunction loadImage( url ) {\n\n\t\t\t\tscope.manager.itemStart( url );\n\n\t\t\t\treturn loader.load( url, function () {\n\n\t\t\t\t\tscope.manager.itemEnd( url );\n\n\t\t\t\t}, undefined, function () {\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\tif ( json !== undefined && json.length > 0 ) {\n\n\t\t\t\tvar manager = new LoadingManager( onLoad );\n\n\t\t\t\tvar loader = new ImageLoader( manager );\n\t\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar image = json[ i ];\n\t\t\t\t\tvar path = /^(\\/\\/)|([a-z]+:(\\/\\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;\n\n\t\t\t\t\timages[ image.uuid ] = loadImage( path );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn images;\n\n\t\t},\n\n\t\tparseTextures: function ( json, images ) {\n\n\t\t\tvar TextureMapping = {\n\t\t\t\tUVMapping: UVMapping,\n\t\t\t\tCubeReflectionMapping: CubeReflectionMapping,\n\t\t\t\tCubeRefractionMapping: CubeRefractionMapping,\n\t\t\t\tEquirectangularReflectionMapping: EquirectangularReflectionMapping,\n\t\t\t\tEquirectangularRefractionMapping: EquirectangularRefractionMapping,\n\t\t\t\tSphericalReflectionMapping: SphericalReflectionMapping,\n\t\t\t\tCubeUVReflectionMapping: CubeUVReflectionMapping,\n\t\t\t\tCubeUVRefractionMapping: CubeUVRefractionMapping\n\t\t\t};\n\n\t\t\tvar TextureWrapping = {\n\t\t\t\tRepeatWrapping: RepeatWrapping,\n\t\t\t\tClampToEdgeWrapping: ClampToEdgeWrapping,\n\t\t\t\tMirroredRepeatWrapping: MirroredRepeatWrapping\n\t\t\t};\n\n\t\t\tvar TextureFilter = {\n\t\t\t\tNearestFilter: NearestFilter,\n\t\t\t\tNearestMipMapNearestFilter: NearestMipMapNearestFilter,\n\t\t\t\tNearestMipMapLinearFilter: NearestMipMapLinearFilter,\n\t\t\t\tLinearFilter: LinearFilter,\n\t\t\t\tLinearMipMapNearestFilter: LinearMipMapNearestFilter,\n\t\t\t\tLinearMipMapLinearFilter: LinearMipMapLinearFilter\n\t\t\t};\n\n\t\t\tfunction parseConstant( value, type ) {\n\n\t\t\t\tif ( typeof( value ) === 'number' ) return value;\n\n\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );\n\n\t\t\t\treturn type[ value ];\n\n\t\t\t}\n\n\t\t\tvar textures = {};\n\n\t\t\tif ( json !== undefined ) {\n\n\t\t\t\tfor ( var i = 0, l = json.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar data = json[ i ];\n\n\t\t\t\t\tif ( data.image === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: No \"image\" specified for', data.uuid );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( images[ data.image ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined image', data.image );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar texture = new Texture( images[ data.image ] );\n\t\t\t\t\ttexture.needsUpdate = true;\n\n\t\t\t\t\ttexture.uuid = data.uuid;\n\n\t\t\t\t\tif ( data.name !== undefined ) texture.name = data.name;\n\n\t\t\t\t\tif ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );\n\n\t\t\t\t\tif ( data.offset !== undefined ) texture.offset.fromArray( data.offset );\n\t\t\t\t\tif ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );\n\t\t\t\t\tif ( data.wrap !== undefined ) {\n\n\t\t\t\t\t\ttexture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );\n\t\t\t\t\t\ttexture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );\n\t\t\t\t\tif ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );\n\t\t\t\t\tif ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;\n\n\t\t\t\t\tif ( data.flipY !== undefined ) texture.flipY = data.flipY;\n\n\t\t\t\t\ttextures[ data.uuid ] = texture;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn textures;\n\n\t\t},\n\n\t\tparseObject: function () {\n\n\t\t\tvar matrix = new Matrix4();\n\n\t\t\treturn function parseObject( data, geometries, materials ) {\n\n\t\t\t\tvar object;\n\n\t\t\t\tfunction getGeometry( name ) {\n\n\t\t\t\t\tif ( geometries[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined geometry', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn geometries[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tfunction getMaterial( name ) {\n\n\t\t\t\t\tif ( name === undefined ) return undefined;\n\n\t\t\t\t\tif ( materials[ name ] === undefined ) {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader: Undefined material', name );\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn materials[ name ];\n\n\t\t\t\t}\n\n\t\t\t\tswitch ( data.type ) {\n\n\t\t\t\t\tcase 'Scene':\n\n\t\t\t\t\t\tobject = new Scene();\n\n\t\t\t\t\t\tif ( data.background !== undefined ) {\n\n\t\t\t\t\t\t\tif ( Number.isInteger( data.background ) ) {\n\n\t\t\t\t\t\t\t\tobject.background = new Color( data.background );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( data.fog !== undefined ) {\n\n\t\t\t\t\t\t\tif ( data.fog.type === 'Fog' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );\n\n\t\t\t\t\t\t\t} else if ( data.fog.type === 'FogExp2' ) {\n\n\t\t\t\t\t\t\t\tobject.fog = new FogExp2( data.fog.color, data.fog.density );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PerspectiveCamera':\n\n\t\t\t\t\t\tobject = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );\n\n\t\t\t\t\t\tif ( data.focus !== undefined ) object.focus = data.focus;\n\t\t\t\t\t\tif ( data.zoom !== undefined ) object.zoom = data.zoom;\n\t\t\t\t\t\tif ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;\n\t\t\t\t\t\tif ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;\n\t\t\t\t\t\tif ( data.view !== undefined ) object.view = Object.assign( {}, data.view );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'OrthographicCamera':\n\n\t\t\t\t\t\tobject = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'AmbientLight':\n\n\t\t\t\t\t\tobject = new AmbientLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'DirectionalLight':\n\n\t\t\t\t\t\tobject = new DirectionalLight( data.color, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointLight':\n\n\t\t\t\t\t\tobject = new PointLight( data.color, data.intensity, data.distance, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SpotLight':\n\n\t\t\t\t\t\tobject = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'HemisphereLight':\n\n\t\t\t\t\t\tobject = new HemisphereLight( data.color, data.groundColor, data.intensity );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Mesh':\n\n\t\t\t\t\t\tvar geometry = getGeometry( data.geometry );\n\t\t\t\t\t\tvar material = getMaterial( data.material );\n\n\t\t\t\t\t\tif ( geometry.bones && geometry.bones.length > 0 ) {\n\n\t\t\t\t\t\t\tobject = new SkinnedMesh( geometry, material );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tobject = new Mesh( geometry, material );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LOD':\n\n\t\t\t\t\t\tobject = new LOD();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Line':\n\n\t\t\t\t\t\tobject = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'LineSegments':\n\n\t\t\t\t\t\tobject = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'PointCloud':\n\t\t\t\t\tcase 'Points':\n\n\t\t\t\t\t\tobject = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Sprite':\n\n\t\t\t\t\t\tobject = new Sprite( getMaterial( data.material ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'Group':\n\n\t\t\t\t\t\tobject = new Group();\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'SkinnedMesh':\n\n\t\t\t\t\t\tconsole.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tobject = new Object3D();\n\n\t\t\t\t}\n\n\t\t\t\tobject.uuid = data.uuid;\n\n\t\t\t\tif ( data.name !== undefined ) object.name = data.name;\n\t\t\t\tif ( data.matrix !== undefined ) {\n\n\t\t\t\t\tmatrix.fromArray( data.matrix );\n\t\t\t\t\tmatrix.decompose( object.position, object.quaternion, object.scale );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tif ( data.position !== undefined ) object.position.fromArray( data.position );\n\t\t\t\t\tif ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );\n\t\t\t\t\tif ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );\n\t\t\t\t\tif ( data.scale !== undefined ) object.scale.fromArray( data.scale );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.castShadow !== undefined ) object.castShadow = data.castShadow;\n\t\t\t\tif ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;\n\n\t\t\t\tif ( data.shadow ) {\n\n\t\t\t\t\tif ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;\n\t\t\t\t\tif ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;\n\t\t\t\t\tif ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );\n\t\t\t\t\tif ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.visible !== undefined ) object.visible = data.visible;\n\t\t\t\tif ( data.userData !== undefined ) object.userData = data.userData;\n\n\t\t\t\tif ( data.children !== undefined ) {\n\n\t\t\t\t\tfor ( var child in data.children ) {\n\n\t\t\t\t\t\tobject.add( this.parseObject( data.children[ child ], geometries, materials ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( data.type === 'LOD' ) {\n\n\t\t\t\t\tvar levels = data.levels;\n\n\t\t\t\t\tfor ( var l = 0; l < levels.length; l ++ ) {\n\n\t\t\t\t\t\tvar level = levels[ l ];\n\t\t\t\t\t\tvar child = object.getObjectByProperty( 'uuid', level.object );\n\n\t\t\t\t\t\tif ( child !== undefined ) {\n\n\t\t\t\t\t\t\tobject.addLevel( child, level.distance );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn object;\n\n\t\t\t};\n\n\t\t}()\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t * Bezier Curves formulas obtained from\n\t * http://en.wikipedia.org/wiki/Bézier_curve\n\t */\n\n\tfunction CatmullRom( t, p0, p1, p2, p3 ) {\n\n\t\tvar v0 = ( p2 - p0 ) * 0.5;\n\t\tvar v1 = ( p3 - p1 ) * 0.5;\n\t\tvar t2 = t * t;\n\t\tvar t3 = t * t2;\n\t\treturn ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;\n\n\t}\n\n\t//\n\n\tfunction QuadraticBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * p;\n\n\t}\n\n\tfunction QuadraticBezierP1( t, p ) {\n\n\t\treturn 2 * ( 1 - t ) * t * p;\n\n\t}\n\n\tfunction QuadraticBezierP2( t, p ) {\n\n\t\treturn t * t * p;\n\n\t}\n\n\tfunction QuadraticBezier( t, p0, p1, p2 ) {\n\n\t\treturn QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +\n\t\t\tQuadraticBezierP2( t, p2 );\n\n\t}\n\n\t//\n\n\tfunction CubicBezierP0( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn k * k * k * p;\n\n\t}\n\n\tfunction CubicBezierP1( t, p ) {\n\n\t\tvar k = 1 - t;\n\t\treturn 3 * k * k * t * p;\n\n\t}\n\n\tfunction CubicBezierP2( t, p ) {\n\n\t\treturn 3 * ( 1 - t ) * t * t * p;\n\n\t}\n\n\tfunction CubicBezierP3( t, p ) {\n\n\t\treturn t * t * t * p;\n\n\t}\n\n\tfunction CubicBezier( t, p0, p1, p2, p3 ) {\n\n\t\treturn CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +\n\t\t\tCubicBezierP3( t, p3 );\n\n\t}\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Extensible curve object\n\t *\n\t * Some common of Curve methods\n\t * .getPoint(t), getTangent(t)\n\t * .getPointAt(u), getTangentAt(u)\n\t * .getPoints(), .getSpacedPoints()\n\t * .getLength()\n\t * .updateArcLengths()\n\t *\n\t * This following classes subclasses THREE.Curve:\n\t *\n\t * -- 2d classes --\n\t * THREE.LineCurve\n\t * THREE.QuadraticBezierCurve\n\t * THREE.CubicBezierCurve\n\t * THREE.SplineCurve\n\t * THREE.ArcCurve\n\t * THREE.EllipseCurve\n\t *\n\t * -- 3d classes --\n\t * THREE.LineCurve3\n\t * THREE.QuadraticBezierCurve3\n\t * THREE.CubicBezierCurve3\n\t * THREE.CatmullRomCurve3\n\t *\n\t * A series of curves can be represented as a THREE.CurvePath\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tAbstract Curve base class\n\t **************************************************************/\n\n\tfunction Curve() {}\n\n\tCurve.prototype = {\n\n\t\tconstructor: Curve,\n\n\t\t// Virtual base class method to overwrite and implement in subclasses\n\t\t//\t- t [0 .. 1]\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tconsole.warn( \"THREE.Curve: Warning, getPoint() not implemented!\" );\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// Get point at relative position in curve according to arc length\n\t\t// - u [0 .. 1]\n\n\t\tgetPointAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getPoint( t );\n\n\t\t},\n\n\t\t// Get sequence of points using getPoint( t )\n\n\t\tgetPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPoint( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get sequence of points using getPointAt( u )\n\n\t\tgetSpacedPoints: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = 5;\n\n\t\t\tvar points = [];\n\n\t\t\tfor ( var d = 0; d <= divisions; d ++ ) {\n\n\t\t\t\tpoints.push( this.getPointAt( d / divisions ) );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t// Get total curve arc length\n\n\t\tgetLength: function () {\n\n\t\t\tvar lengths = this.getLengths();\n\t\t\treturn lengths[ lengths.length - 1 ];\n\n\t\t},\n\n\t\t// Get list of cumulative segment lengths\n\n\t\tgetLengths: function ( divisions ) {\n\n\t\t\tif ( isNaN( divisions ) ) divisions = ( this.__arcLengthDivisions ) ? ( this.__arcLengthDivisions ) : 200;\n\n\t\t\tif ( this.cacheArcLengths\n\t\t\t\t&& ( this.cacheArcLengths.length === divisions + 1 )\n\t\t\t\t&& ! this.needsUpdate ) {\n\n\t\t\t\t//console.log( \"cached\", this.cacheArcLengths );\n\t\t\t\treturn this.cacheArcLengths;\n\n\t\t\t}\n\n\t\t\tthis.needsUpdate = false;\n\n\t\t\tvar cache = [];\n\t\t\tvar current, last = this.getPoint( 0 );\n\t\t\tvar p, sum = 0;\n\n\t\t\tcache.push( 0 );\n\n\t\t\tfor ( p = 1; p <= divisions; p ++ ) {\n\n\t\t\t\tcurrent = this.getPoint ( p / divisions );\n\t\t\t\tsum += current.distanceTo( last );\n\t\t\t\tcache.push( sum );\n\t\t\t\tlast = current;\n\n\t\t\t}\n\n\t\t\tthis.cacheArcLengths = cache;\n\n\t\t\treturn cache; // { sums: cache, sum:sum }; Sum is in the last element.\n\n\t\t},\n\n\t\tupdateArcLengths: function() {\n\n\t\t\tthis.needsUpdate = true;\n\t\t\tthis.getLengths();\n\n\t\t},\n\n\t\t// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant\n\n\t\tgetUtoTmapping: function ( u, distance ) {\n\n\t\t\tvar arcLengths = this.getLengths();\n\n\t\t\tvar i = 0, il = arcLengths.length;\n\n\t\t\tvar targetArcLength; // The targeted u distance value to get\n\n\t\t\tif ( distance ) {\n\n\t\t\t\ttargetArcLength = distance;\n\n\t\t\t} else {\n\n\t\t\t\ttargetArcLength = u * arcLengths[ il - 1 ];\n\n\t\t\t}\n\n\t\t\t//var time = Date.now();\n\n\t\t\t// binary search for the index with largest value smaller than target u distance\n\n\t\t\tvar low = 0, high = il - 1, comparison;\n\n\t\t\twhile ( low <= high ) {\n\n\t\t\t\ti = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats\n\n\t\t\t\tcomparison = arcLengths[ i ] - targetArcLength;\n\n\t\t\t\tif ( comparison < 0 ) {\n\n\t\t\t\t\tlow = i + 1;\n\n\t\t\t\t} else if ( comparison > 0 ) {\n\n\t\t\t\t\thigh = i - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\thigh = i;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\t// DONE\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ti = high;\n\n\t\t\t//console.log('b' , i, low, high, Date.now()- time);\n\n\t\t\tif ( arcLengths[ i ] === targetArcLength ) {\n\n\t\t\t\tvar t = i / ( il - 1 );\n\t\t\t\treturn t;\n\n\t\t\t}\n\n\t\t\t// we could get finer grain at lengths, or use simple interpolation between two points\n\n\t\t\tvar lengthBefore = arcLengths[ i ];\n\t\t\tvar lengthAfter = arcLengths[ i + 1 ];\n\n\t\t\tvar segmentLength = lengthAfter - lengthBefore;\n\n\t\t\t// determine where we are between the 'before' and 'after' points\n\n\t\t\tvar segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;\n\n\t\t\t// add that fractional amount to t\n\n\t\t\tvar t = ( i + segmentFraction ) / ( il - 1 );\n\n\t\t\treturn t;\n\n\t\t},\n\n\t\t// Returns a unit vector tangent at t\n\t\t// In case any sub curve does not implement its tangent derivation,\n\t\t// 2 points a small delta apart will be used to find its gradient\n\t\t// which seems to give a reasonable approximation\n\n\t\tgetTangent: function( t ) {\n\n\t\t\tvar delta = 0.0001;\n\t\t\tvar t1 = t - delta;\n\t\t\tvar t2 = t + delta;\n\n\t\t\t// Capping in case of danger\n\n\t\t\tif ( t1 < 0 ) t1 = 0;\n\t\t\tif ( t2 > 1 ) t2 = 1;\n\n\t\t\tvar pt1 = this.getPoint( t1 );\n\t\t\tvar pt2 = this.getPoint( t2 );\n\n\t\t\tvar vec = pt2.clone().sub( pt1 );\n\t\t\treturn vec.normalize();\n\n\t\t},\n\n\t\tgetTangentAt: function ( u ) {\n\n\t\t\tvar t = this.getUtoTmapping( u );\n\t\t\treturn this.getTangent( t );\n\n\t\t},\n\n\t\tcomputeFrenetFrames: function ( segments, closed ) {\n\n\t\t\t// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf\n\n\t\t\tvar normal = new Vector3();\n\n\t\t\tvar tangents = [];\n\t\t\tvar normals = [];\n\t\t\tvar binormals = [];\n\n\t\t\tvar vec = new Vector3();\n\t\t\tvar mat = new Matrix4();\n\n\t\t\tvar i, u, theta;\n\n\t\t\t// compute the tangent vectors for each segment on the curve\n\n\t\t\tfor ( i = 0; i <= segments; i ++ ) {\n\n\t\t\t\tu = i / segments;\n\n\t\t\t\ttangents[ i ] = this.getTangentAt( u );\n\t\t\t\ttangents[ i ].normalize();\n\n\t\t\t}\n\n\t\t\t// select an initial normal vector perpendicular to the first tangent vector,\n\t\t\t// and in the direction of the minimum tangent xyz component\n\n\t\t\tnormals[ 0 ] = new Vector3();\n\t\t\tbinormals[ 0 ] = new Vector3();\n\t\t\tvar min = Number.MAX_VALUE;\n\t\t\tvar tx = Math.abs( tangents[ 0 ].x );\n\t\t\tvar ty = Math.abs( tangents[ 0 ].y );\n\t\t\tvar tz = Math.abs( tangents[ 0 ].z );\n\n\t\t\tif ( tx <= min ) {\n\n\t\t\t\tmin = tx;\n\t\t\t\tnormal.set( 1, 0, 0 );\n\n\t\t\t}\n\n\t\t\tif ( ty <= min ) {\n\n\t\t\t\tmin = ty;\n\t\t\t\tnormal.set( 0, 1, 0 );\n\n\t\t\t}\n\n\t\t\tif ( tz <= min ) {\n\n\t\t\t\tnormal.set( 0, 0, 1 );\n\n\t\t\t}\n\n\t\t\tvec.crossVectors( tangents[ 0 ], normal ).normalize();\n\n\t\t\tnormals[ 0 ].crossVectors( tangents[ 0 ], vec );\n\t\t\tbinormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );\n\n\n\t\t\t// compute the slowly-varying normal and binormal vectors for each segment on the curve\n\n\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\tnormals[ i ] = normals[ i - 1 ].clone();\n\n\t\t\t\tbinormals[ i ] = binormals[ i - 1 ].clone();\n\n\t\t\t\tvec.crossVectors( tangents[ i - 1 ], tangents[ i ] );\n\n\t\t\t\tif ( vec.length() > Number.EPSILON ) {\n\n\t\t\t\t\tvec.normalize();\n\n\t\t\t\t\ttheta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors\n\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );\n\n\t\t\t\t}\n\n\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t}\n\n\t\t\t// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same\n\n\t\t\tif ( closed === true ) {\n\n\t\t\t\ttheta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );\n\t\t\t\ttheta /= segments;\n\n\t\t\t\tif ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {\n\n\t\t\t\t\ttheta = - theta;\n\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 1; i <= segments; i ++ ) {\n\n\t\t\t\t\t// twist a little...\n\t\t\t\t\tnormals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );\n\t\t\t\t\tbinormals[ i ].crossVectors( tangents[ i ], normals[ i ] );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttangents: tangents,\n\t\t\t\tnormals: normals,\n\t\t\t\tbinormals: binormals\n\t\t\t};\n\n\t\t}\n\n\t};\n\n\tfunction LineCurve( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve.prototype = Object.create( Curve.prototype );\n\tLineCurve.prototype.constructor = LineCurve;\n\n\tLineCurve.prototype.isLineCurve = true;\n\n\tLineCurve.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar point = this.v2.clone().sub( this.v1 );\n\t\tpoint.multiplyScalar( t ).add( this.v1 );\n\n\t\treturn point;\n\n\t};\n\n\t// Line curve is linear, so we can overwrite default getPointAt\n\n\tLineCurve.prototype.getPointAt = function ( u ) {\n\n\t\treturn this.getPoint( u );\n\n\t};\n\n\tLineCurve.prototype.getTangent = function ( t ) {\n\n\t\tvar tangent = this.v2.clone().sub( this.v1 );\n\n\t\treturn tangent.normalize();\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t *\n\t **/\n\n\t/**************************************************************\n\t *\tCurved Path - a curve path is simply a array of connected\n\t * curves, but retains the api of a curve\n\t **************************************************************/\n\n\tfunction CurvePath() {\n\n\t\tthis.curves = [];\n\n\t\tthis.autoClose = false; // Automatically closes the path\n\n\t}\n\n\tCurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {\n\n\t\tconstructor: CurvePath,\n\n\t\tadd: function ( curve ) {\n\n\t\t\tthis.curves.push( curve );\n\n\t\t},\n\n\t\tclosePath: function () {\n\n\t\t\t// Add a line curve if start and end of lines are not connected\n\t\t\tvar startPoint = this.curves[ 0 ].getPoint( 0 );\n\t\t\tvar endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );\n\n\t\t\tif ( ! startPoint.equals( endPoint ) ) {\n\n\t\t\t\tthis.curves.push( new LineCurve( endPoint, startPoint ) );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// To get accurate point with reference to\n\t\t// entire path distance at time t,\n\t\t// following has to be done:\n\n\t\t// 1. Length of each sub path have to be known\n\t\t// 2. Locate and identify type of curve\n\t\t// 3. Get t for the curve\n\t\t// 4. Return curve.getPointAt(t')\n\n\t\tgetPoint: function ( t ) {\n\n\t\t\tvar d = t * this.getLength();\n\t\t\tvar curveLengths = this.getCurveLengths();\n\t\t\tvar i = 0;\n\n\t\t\t// To think about boundaries points.\n\n\t\t\twhile ( i < curveLengths.length ) {\n\n\t\t\t\tif ( curveLengths[ i ] >= d ) {\n\n\t\t\t\t\tvar diff = curveLengths[ i ] - d;\n\t\t\t\t\tvar curve = this.curves[ i ];\n\n\t\t\t\t\tvar segmentLength = curve.getLength();\n\t\t\t\t\tvar u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;\n\n\t\t\t\t\treturn curve.getPointAt( u );\n\n\t\t\t\t}\n\n\t\t\t\ti ++;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t\t// loop where sum != 0, sum > d , sum+1 1 && !points[ points.length - 1 ].equals( points[ 0 ] ) ) {\n\n\t\t\t\tpoints.push( points[ 0 ] );\n\n\t\t\t}\n\n\t\t\treturn points;\n\n\t\t},\n\n\t\t/**************************************************************\n\t\t *\tCreate Geometries Helpers\n\t\t **************************************************************/\n\n\t\t/// Generate geometry from path points (for Line or Points objects)\n\n\t\tcreatePointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\t// Generate geometry from equidistant sampling along the path\n\n\t\tcreateSpacedPointsGeometry: function ( divisions ) {\n\n\t\t\tvar pts = this.getSpacedPoints( divisions );\n\t\t\treturn this.createGeometry( pts );\n\n\t\t},\n\n\t\tcreateGeometry: function ( points ) {\n\n\t\t\tvar geometry = new Geometry();\n\n\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\tvar point = points[ i ];\n\t\t\t\tgeometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );\n\n\t\t\t}\n\n\t\t\treturn geometry;\n\n\t\t}\n\n\t} );\n\n\tfunction EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\tthis.aX = aX;\n\t\tthis.aY = aY;\n\n\t\tthis.xRadius = xRadius;\n\t\tthis.yRadius = yRadius;\n\n\t\tthis.aStartAngle = aStartAngle;\n\t\tthis.aEndAngle = aEndAngle;\n\n\t\tthis.aClockwise = aClockwise;\n\n\t\tthis.aRotation = aRotation || 0;\n\n\t}\n\n\tEllipseCurve.prototype = Object.create( Curve.prototype );\n\tEllipseCurve.prototype.constructor = EllipseCurve;\n\n\tEllipseCurve.prototype.isEllipseCurve = true;\n\n\tEllipseCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar twoPi = Math.PI * 2;\n\t\tvar deltaAngle = this.aEndAngle - this.aStartAngle;\n\t\tvar samePoints = Math.abs( deltaAngle ) < Number.EPSILON;\n\n\t\t// ensures that deltaAngle is 0 .. 2 PI\n\t\twhile ( deltaAngle < 0 ) deltaAngle += twoPi;\n\t\twhile ( deltaAngle > twoPi ) deltaAngle -= twoPi;\n\n\t\tif ( deltaAngle < Number.EPSILON ) {\n\n\t\t\tif ( samePoints ) {\n\n\t\t\t\tdeltaAngle = 0;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.aClockwise === true && ! samePoints ) {\n\n\t\t\tif ( deltaAngle === twoPi ) {\n\n\t\t\t\tdeltaAngle = - twoPi;\n\n\t\t\t} else {\n\n\t\t\t\tdeltaAngle = deltaAngle - twoPi;\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar angle = this.aStartAngle + t * deltaAngle;\n\t\tvar x = this.aX + this.xRadius * Math.cos( angle );\n\t\tvar y = this.aY + this.yRadius * Math.sin( angle );\n\n\t\tif ( this.aRotation !== 0 ) {\n\n\t\t\tvar cos = Math.cos( this.aRotation );\n\t\t\tvar sin = Math.sin( this.aRotation );\n\n\t\t\tvar tx = x - this.aX;\n\t\t\tvar ty = y - this.aY;\n\n\t\t\t// Rotate the point about the center of the ellipse.\n\t\t\tx = tx * cos - ty * sin + this.aX;\n\t\t\ty = tx * sin + ty * cos + this.aY;\n\n\t\t}\n\n\t\treturn new Vector2( x, y );\n\n\t};\n\n\tfunction SplineCurve( points /* array of Vector2 */ ) {\n\n\t\tthis.points = ( points === undefined ) ? [] : points;\n\n\t}\n\n\tSplineCurve.prototype = Object.create( Curve.prototype );\n\tSplineCurve.prototype.constructor = SplineCurve;\n\n\tSplineCurve.prototype.isSplineCurve = true;\n\n\tSplineCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar point = ( points.length - 1 ) * t;\n\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tvar point0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];\n\t\tvar point1 = points[ intPoint ];\n\t\tvar point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];\n\t\tvar point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];\n\n\t\treturn new Vector2(\n\t\t\tCatmullRom( weight, point0.x, point1.x, point2.x, point3.x ),\n\t\t\tCatmullRom( weight, point0.y, point1.y, point2.y, point3.y )\n\t\t);\n\n\t};\n\n\tfunction CubicBezierCurve( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve.prototype.constructor = CubicBezierCurve;\n\n\tCubicBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector2(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;\n\n\tQuadraticBezierCurve.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector2(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y )\n\t\t);\n\n\t};\n\n\tvar PathPrototype = Object.assign( Object.create( CurvePath.prototype ), {\n\n\t\tfromPoints: function ( vectors ) {\n\n\t\t\tthis.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );\n\n\t\t\tfor ( var i = 1, l = vectors.length; i < l; i ++ ) {\n\n\t\t\t\tthis.lineTo( vectors[ i ].x, vectors[ i ].y );\n\n\t\t\t}\n\n\t\t},\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tvar curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tvar curve = new QuadraticBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCPx, aCPy ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tvar curve = new CubicBezierCurve(\n\t\t\t\tthis.currentPoint.clone(),\n\t\t\t\tnew Vector2( aCP1x, aCP1y ),\n\t\t\t\tnew Vector2( aCP2x, aCP2y ),\n\t\t\t\tnew Vector2( aX, aY )\n\t\t\t);\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.set( aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts /*Array of Vector*/ ) {\n\n\t\t\tvar npts = [ this.currentPoint.clone() ].concat( pts );\n\n\t\t\tvar curve = new SplineCurve( npts );\n\t\t\tthis.curves.push( curve );\n\n\t\t\tthis.currentPoint.copy( pts[ pts.length - 1 ] );\n\n\t\t},\n\n\t\tarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absarc( aX + x0, aY + y0, aRadius,\n\t\t\t\taStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tabsarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\t\tthis.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t\t},\n\n\t\tellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar x0 = this.currentPoint.x;\n\t\t\tvar y0 = this.currentPoint.y;\n\n\t\t\tthis.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t},\n\n\t\tabsellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {\n\n\t\t\tvar curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );\n\n\t\t\tif ( this.curves.length > 0 ) {\n\n\t\t\t\t// if a previous curve is present, attempt to join\n\t\t\t\tvar firstPoint = curve.getPoint( 0 );\n\n\t\t\t\tif ( ! firstPoint.equals( this.currentPoint ) ) {\n\n\t\t\t\t\tthis.lineTo( firstPoint.x, firstPoint.y );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.curves.push( curve );\n\n\t\t\tvar lastPoint = curve.getPoint( 1 );\n\t\t\tthis.currentPoint.copy( lastPoint );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Creates free form 2d path using series of points, lines or curves.\n\t **/\n\n\tfunction Path( points ) {\n\n\t\tCurvePath.call( this );\n\t\tthis.currentPoint = new Vector2();\n\n\t\tif ( points ) {\n\n\t\t\tthis.fromPoints( points );\n\n\t\t}\n\n\t}\n\n\tPath.prototype = PathPrototype;\n\tPathPrototype.constructor = Path;\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * Defines a 2d shape plane using paths.\n\t **/\n\n\t// STEP 1 Create a path.\n\t// STEP 2 Turn path into shape.\n\t// STEP 3 ExtrudeGeometry takes in Shape/Shapes\n\t// STEP 3a - Extract points from each shape, turn to vertices\n\t// STEP 3b - Triangulate each shape, add faces.\n\n\tfunction Shape() {\n\n\t\tPath.apply( this, arguments );\n\n\t\tthis.holes = [];\n\n\t}\n\n\tShape.prototype = Object.assign( Object.create( PathPrototype ), {\n\n\t\tconstructor: Shape,\n\n\t\tgetPointsHoles: function ( divisions ) {\n\n\t\t\tvar holesPts = [];\n\n\t\t\tfor ( var i = 0, l = this.holes.length; i < l; i ++ ) {\n\n\t\t\t\tholesPts[ i ] = this.holes[ i ].getPoints( divisions );\n\n\t\t\t}\n\n\t\t\treturn holesPts;\n\n\t\t},\n\n\t\t// Get points of shape and holes (keypoints based on segments parameter)\n\n\t\textractAllPoints: function ( divisions ) {\n\n\t\t\treturn {\n\n\t\t\t\tshape: this.getPoints( divisions ),\n\t\t\t\tholes: this.getPointsHoles( divisions )\n\n\t\t\t};\n\n\t\t},\n\n\t\textractPoints: function ( divisions ) {\n\n\t\t\treturn this.extractAllPoints( divisions );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * minimal class for proxing functions to Path. Replaces old \"extractSubpaths()\"\n\t **/\n\n\tfunction ShapePath() {\n\n\t\tthis.subPaths = [];\n\t\tthis.currentPath = null;\n\n\t}\n\n\tShapePath.prototype = {\n\n\t\tmoveTo: function ( x, y ) {\n\n\t\t\tthis.currentPath = new Path();\n\t\t\tthis.subPaths.push( this.currentPath );\n\t\t\tthis.currentPath.moveTo( x, y );\n\n\t\t},\n\n\t\tlineTo: function ( x, y ) {\n\n\t\t\tthis.currentPath.lineTo( x, y );\n\n\t\t},\n\n\t\tquadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {\n\n\t\t\tthis.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );\n\n\t\t},\n\n\t\tbezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {\n\n\t\t\tthis.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );\n\n\t\t},\n\n\t\tsplineThru: function ( pts ) {\n\n\t\t\tthis.currentPath.splineThru( pts );\n\n\t\t},\n\n\t\ttoShapes: function ( isCCW, noHoles ) {\n\n\t\t\tfunction toShapesNoHoles( inSubpaths ) {\n\n\t\t\t\tvar shapes = [];\n\n\t\t\t\tfor ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar tmpPath = inSubpaths[ i ];\n\n\t\t\t\t\tvar tmpShape = new Shape();\n\t\t\t\t\ttmpShape.curves = tmpPath.curves;\n\n\t\t\t\t\tshapes.push( tmpShape );\n\n\t\t\t\t}\n\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tfunction isPointInsidePolygon( inPt, inPolygon ) {\n\n\t\t\t\tvar polyLen = inPolygon.length;\n\n\t\t\t\t// inPt on polygon contour => immediate success or\n\t\t\t\t// toggling of inside/outside at every single! intersection point of an edge\n\t\t\t\t// with the horizontal line through inPt, left of inPt\n\t\t\t\t// not counting lowerY endpoints of edges and whole edges on that line\n\t\t\t\tvar inside = false;\n\t\t\t\tfor ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {\n\n\t\t\t\t\tvar edgeLowPt = inPolygon[ p ];\n\t\t\t\t\tvar edgeHighPt = inPolygon[ q ];\n\n\t\t\t\t\tvar edgeDx = edgeHighPt.x - edgeLowPt.x;\n\t\t\t\t\tvar edgeDy = edgeHighPt.y - edgeLowPt.y;\n\n\t\t\t\t\tif ( Math.abs( edgeDy ) > Number.EPSILON ) {\n\n\t\t\t\t\t\t// not parallel\n\t\t\t\t\t\tif ( edgeDy < 0 ) {\n\n\t\t\t\t\t\t\tedgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;\n\t\t\t\t\t\t\tedgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) \t\tcontinue;\n\n\t\t\t\t\t\tif ( inPt.y === edgeLowPt.y ) {\n\n\t\t\t\t\t\t\tif ( inPt.x === edgeLowPt.x )\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\t// continue;\t\t\t\t// no intersection or edgeLowPt => doesn't count !!!\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tvar perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );\n\t\t\t\t\t\t\tif ( perpEdge === 0 )\t\t\t\treturn\ttrue;\t\t// inPt is on contour ?\n\t\t\t\t\t\t\tif ( perpEdge < 0 ) \t\t\t\tcontinue;\n\t\t\t\t\t\t\tinside = ! inside;\t\t// true intersection left of inPt\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// parallel or collinear\n\t\t\t\t\t\tif ( inPt.y !== edgeLowPt.y ) \t\tcontinue;\t\t\t// parallel\n\t\t\t\t\t\t// edge lies on the same horizontal line as inPt\n\t\t\t\t\t\tif ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||\n\t\t\t\t\t\t\t ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )\t\treturn\ttrue;\t// inPt: Point on contour !\n\t\t\t\t\t\t// continue;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn\tinside;\n\n\t\t\t}\n\n\t\t\tvar isClockWise = ShapeUtils.isClockWise;\n\n\t\t\tvar subPaths = this.subPaths;\n\t\t\tif ( subPaths.length === 0 ) return [];\n\n\t\t\tif ( noHoles === true )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tvar solid, tmpPath, tmpShape, shapes = [];\n\n\t\t\tif ( subPaths.length === 1 ) {\n\n\t\t\t\ttmpPath = subPaths[ 0 ];\n\t\t\t\ttmpShape = new Shape();\n\t\t\t\ttmpShape.curves = tmpPath.curves;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\treturn shapes;\n\n\t\t\t}\n\n\t\t\tvar holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );\n\t\t\tholesFirst = isCCW ? ! holesFirst : holesFirst;\n\n\t\t\t// console.log(\"Holes first\", holesFirst);\n\n\t\t\tvar betterShapeHoles = [];\n\t\t\tvar newShapes = [];\n\t\t\tvar newShapeHoles = [];\n\t\t\tvar mainIdx = 0;\n\t\t\tvar tmpPoints;\n\n\t\t\tnewShapes[ mainIdx ] = undefined;\n\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\tfor ( var i = 0, l = subPaths.length; i < l; i ++ ) {\n\n\t\t\t\ttmpPath = subPaths[ i ];\n\t\t\t\ttmpPoints = tmpPath.getPoints();\n\t\t\t\tsolid = isClockWise( tmpPoints );\n\t\t\t\tsolid = isCCW ? ! solid : solid;\n\n\t\t\t\tif ( solid ) {\n\n\t\t\t\t\tif ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )\tmainIdx ++;\n\n\t\t\t\t\tnewShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };\n\t\t\t\t\tnewShapes[ mainIdx ].s.curves = tmpPath.curves;\n\n\t\t\t\t\tif ( holesFirst )\tmainIdx ++;\n\t\t\t\t\tnewShapeHoles[ mainIdx ] = [];\n\n\t\t\t\t\t//console.log('cw', i);\n\n\t\t\t\t} else {\n\n\t\t\t\t\tnewShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );\n\n\t\t\t\t\t//console.log('ccw', i);\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// only Holes? -> probably all Shapes with wrong orientation\n\t\t\tif ( ! newShapes[ 0 ] )\treturn\ttoShapesNoHoles( subPaths );\n\n\n\t\t\tif ( newShapes.length > 1 ) {\n\n\t\t\t\tvar ambiguous = false;\n\t\t\t\tvar toChange = [];\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tbetterShapeHoles[ sIdx ] = [];\n\n\t\t\t\t}\n\n\t\t\t\tfor ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {\n\n\t\t\t\t\tvar sho = newShapeHoles[ sIdx ];\n\n\t\t\t\t\tfor ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {\n\n\t\t\t\t\t\tvar ho = sho[ hIdx ];\n\t\t\t\t\t\tvar hole_unassigned = true;\n\n\t\t\t\t\t\tfor ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {\n\n\t\t\t\t\t\t\tif ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {\n\n\t\t\t\t\t\t\t\tif ( sIdx !== s2Idx )\ttoChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );\n\t\t\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\t\t\thole_unassigned = false;\n\t\t\t\t\t\t\t\t\tbetterShapeHoles[ s2Idx ].push( ho );\n\n\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\tambiguous = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( hole_unassigned ) {\n\n\t\t\t\t\t\t\tbetterShapeHoles[ sIdx ].push( ho );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\t// console.log(\"ambiguous: \", ambiguous);\n\t\t\t\tif ( toChange.length > 0 ) {\n\n\t\t\t\t\t// console.log(\"to change: \", toChange);\n\t\t\t\t\tif ( ! ambiguous )\tnewShapeHoles = betterShapeHoles;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar tmpHoles;\n\n\t\t\tfor ( var i = 0, il = newShapes.length; i < il; i ++ ) {\n\n\t\t\t\ttmpShape = newShapes[ i ].s;\n\t\t\t\tshapes.push( tmpShape );\n\t\t\t\ttmpHoles = newShapeHoles[ i ];\n\n\t\t\t\tfor ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {\n\n\t\t\t\t\ttmpShape.holes.push( tmpHoles[ j ].h );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//console.log(\"shape\", shapes);\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author zz85 / http://www.lab4games.net/zz85/blog\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Font( data ) {\n\n\t\tthis.data = data;\n\n\t}\n\n\tObject.assign( Font.prototype, {\n\n\t\tisFont: true,\n\n\t\tgenerateShapes: function ( text, size, divisions ) {\n\n\t\t\tfunction createPaths( text ) {\n\n\t\t\t\tvar chars = String( text ).split( '' );\n\t\t\t\tvar scale = size / data.resolution;\n\t\t\t\tvar line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;\n\n\t\t\t\tvar offsetX = 0, offsetY = 0;\n\n\t\t\t\tvar paths = [];\n\n\t\t\t\tfor ( var i = 0; i < chars.length; i ++ ) {\n\n\t\t\t\t\tvar char = chars[ i ];\n\n\t\t\t\t\tif ( char === '\\n' ) {\n\n\t\t\t\t\t\toffsetX = 0;\n\t\t\t\t\t\toffsetY -= line_height;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar ret = createPath( char, scale, offsetX, offsetY );\n\t\t\t\t\t\toffsetX += ret.offsetX;\n\t\t\t\t\t\tpaths.push( ret.path );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn paths;\n\n\t\t\t}\n\n\t\t\tfunction createPath( c, scale, offsetX, offsetY ) {\n\n\t\t\t\tvar glyph = data.glyphs[ c ] || data.glyphs[ '?' ];\n\n\t\t\t\tif ( ! glyph ) return;\n\n\t\t\t\tvar path = new ShapePath();\n\n\t\t\t\tvar pts = [];\n\t\t\t\tvar x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2, laste;\n\n\t\t\t\tif ( glyph.o ) {\n\n\t\t\t\t\tvar outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );\n\n\t\t\t\t\tfor ( var i = 0, l = outline.length; i < l; ) {\n\n\t\t\t\t\t\tvar action = outline[ i ++ ];\n\n\t\t\t\t\t\tswitch ( action ) {\n\n\t\t\t\t\t\t\tcase 'm': // moveTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.moveTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'l': // lineTo\n\n\t\t\t\t\t\t\t\tx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\ty = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.lineTo( x, y );\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'q': // quadraticCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.quadraticCurveTo( cpx1, cpy1, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpx0, cpx1, cpx );\n\t\t\t\t\t\t\t\t\t\tQuadraticBezier( t, cpy0, cpy1, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'b': // bezierCurveTo\n\n\t\t\t\t\t\t\t\tcpx = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx1 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy1 = outline[ i ++ ] * scale + offsetY;\n\t\t\t\t\t\t\t\tcpx2 = outline[ i ++ ] * scale + offsetX;\n\t\t\t\t\t\t\t\tcpy2 = outline[ i ++ ] * scale + offsetY;\n\n\t\t\t\t\t\t\t\tpath.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );\n\n\t\t\t\t\t\t\t\tlaste = pts[ pts.length - 1 ];\n\n\t\t\t\t\t\t\t\tif ( laste ) {\n\n\t\t\t\t\t\t\t\t\tcpx0 = laste.x;\n\t\t\t\t\t\t\t\t\tcpy0 = laste.y;\n\n\t\t\t\t\t\t\t\t\tfor ( var i2 = 1; i2 <= divisions; i2 ++ ) {\n\n\t\t\t\t\t\t\t\t\t\tvar t = i2 / divisions;\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpx0, cpx1, cpx2, cpx );\n\t\t\t\t\t\t\t\t\t\tCubicBezier( t, cpy0, cpy1, cpy2, cpy );\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\treturn { offsetX: glyph.ha * scale, path: path };\n\n\t\t\t}\n\n\t\t\t//\n\n\t\t\tif ( size === undefined ) size = 100;\n\t\t\tif ( divisions === undefined ) divisions = 4;\n\n\t\t\tvar data = this.data;\n\n\t\t\tvar paths = createPaths( text );\n\t\t\tvar shapes = [];\n\n\t\t\tfor ( var p = 0, pl = paths.length; p < pl; p ++ ) {\n\n\t\t\t\tArray.prototype.push.apply( shapes, paths[ p ].toShapes() );\n\n\t\t\t}\n\n\t\t\treturn shapes;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction FontLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( FontLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar scope = this;\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\tvar json;\n\n\t\t\t\ttry {\n\n\t\t\t\t\tjson = JSON.parse( text );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tconsole.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );\n\t\t\t\t\tjson = JSON.parse( text.substring( 65, text.length - 2 ) );\n\n\t\t\t\t}\n\n\t\t\t\tvar font = scope.parse( json );\n\n\t\t\t\tif ( onLoad ) onLoad( font );\n\n\t\t\t}, onProgress, onError );\n\n\t\t},\n\n\t\tparse: function ( json ) {\n\n\t\t\treturn new Font( json );\n\n\t\t}\n\n\t} );\n\n\tvar context;\n\n\tvar AudioContext = {\n\n\t\tgetContext: function () {\n\n\t\t\tif ( context === undefined ) {\n\n\t\t\t\tcontext = new ( window.AudioContext || window.webkitAudioContext )();\n\n\t\t\t}\n\n\t\t\treturn context;\n\n\t\t},\n\n\t\tsetContext: function ( value ) {\n\n\t\t\tcontext = value;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction AudioLoader( manager ) {\n\n\t\tthis.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;\n\n\t}\n\n\tObject.assign( AudioLoader.prototype, {\n\n\t\tload: function ( url, onLoad, onProgress, onError ) {\n\n\t\t\tvar loader = new FileLoader( this.manager );\n\t\t\tloader.setResponseType( 'arraybuffer' );\n\t\t\tloader.load( url, function ( buffer ) {\n\n\t\t\t\tvar context = AudioContext.getContext();\n\n\t\t\t\tcontext.decodeAudioData( buffer, function ( audioBuffer ) {\n\n\t\t\t\t\tonLoad( audioBuffer );\n\n\t\t\t\t} );\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t */\n\n\tfunction RectAreaLight ( color, intensity, width, height ) {\n\n\t\tLight.call( this, color, intensity );\n\n\t\tthis.type = 'RectAreaLight';\n\n\t\tthis.position.set( 0, 1, 0 );\n\t\tthis.updateMatrix();\n\n\t\tthis.width = ( width !== undefined ) ? width : 10;\n\t\tthis.height = ( height !== undefined ) ? height : 10;\n\n\t\t// TODO (abelnation): distance/decay\n\n\t\t// TODO (abelnation): update method for RectAreaLight to update transform to lookat target\n\n\t\t// TODO (abelnation): shadows\n\t\t// this.shadow = new THREE.RectAreaLightShadow( new THREE.PerspectiveCamera( 90, 1, 0.5, 500 ) );\n\n\t}\n\n\t// TODO (abelnation): RectAreaLight update when light shape is changed\n\tRectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {\n\n\t\tconstructor: RectAreaLight,\n\n\t\tisRectAreaLight: true,\n\n\t\tcopy: function ( source ) {\n\n\t\t\tLight.prototype.copy.call( this, source );\n\n\t\t\tthis.width = source.width;\n\t\t\tthis.height = source.height;\n\n\t\t\t// this.shadow = source.shadow.clone();\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction StereoCamera() {\n\n\t\tthis.type = 'StereoCamera';\n\n\t\tthis.aspect = 1;\n\n\t\tthis.eyeSep = 0.064;\n\n\t\tthis.cameraL = new PerspectiveCamera();\n\t\tthis.cameraL.layers.enable( 1 );\n\t\tthis.cameraL.matrixAutoUpdate = false;\n\n\t\tthis.cameraR = new PerspectiveCamera();\n\t\tthis.cameraR.layers.enable( 2 );\n\t\tthis.cameraR.matrixAutoUpdate = false;\n\n\t}\n\n\tObject.assign( StereoCamera.prototype, {\n\n\t\tupdate: ( function () {\n\n\t\t\tvar instance, focus, fov, aspect, near, far, zoom;\n\n\t\t\tvar eyeRight = new Matrix4();\n\t\t\tvar eyeLeft = new Matrix4();\n\n\t\t\treturn function update( camera ) {\n\n\t\t\t\tvar needsUpdate = instance !== this || focus !== camera.focus || fov !== camera.fov ||\n\t\t\t\t\t\t\t\t\t\t\t\t\taspect !== camera.aspect * this.aspect || near !== camera.near ||\n\t\t\t\t\t\t\t\t\t\t\t\t\tfar !== camera.far || zoom !== camera.zoom;\n\n\t\t\t\tif ( needsUpdate ) {\n\n\t\t\t\t\tinstance = this;\n\t\t\t\t\tfocus = camera.focus;\n\t\t\t\t\tfov = camera.fov;\n\t\t\t\t\taspect = camera.aspect * this.aspect;\n\t\t\t\t\tnear = camera.near;\n\t\t\t\t\tfar = camera.far;\n\t\t\t\t\tzoom = camera.zoom;\n\n\t\t\t\t\t// Off-axis stereoscopic effect based on\n\t\t\t\t\t// http://paulbourke.net/stereographics/stereorender/\n\n\t\t\t\t\tvar projectionMatrix = camera.projectionMatrix.clone();\n\t\t\t\t\tvar eyeSep = this.eyeSep / 2;\n\t\t\t\t\tvar eyeSepOnProjection = eyeSep * near / focus;\n\t\t\t\t\tvar ymax = ( near * Math.tan( _Math.DEG2RAD * fov * 0.5 ) ) / zoom;\n\t\t\t\t\tvar xmin, xmax;\n\n\t\t\t\t\t// translate xOffset\n\n\t\t\t\t\teyeLeft.elements[ 12 ] = - eyeSep;\n\t\t\t\t\teyeRight.elements[ 12 ] = eyeSep;\n\n\t\t\t\t\t// for left eye\n\n\t\t\t\t\txmin = - ymax * aspect + eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect + eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraL.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t\t// for right eye\n\n\t\t\t\t\txmin = - ymax * aspect - eyeSepOnProjection;\n\t\t\t\t\txmax = ymax * aspect - eyeSepOnProjection;\n\n\t\t\t\t\tprojectionMatrix.elements[ 0 ] = 2 * near / ( xmax - xmin );\n\t\t\t\t\tprojectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );\n\n\t\t\t\t\tthis.cameraR.projectionMatrix.copy( projectionMatrix );\n\n\t\t\t\t}\n\n\t\t\t\tthis.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( eyeLeft );\n\t\t\t\tthis.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( eyeRight );\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * Camera for rendering cube maps\n\t *\t- renders scene into axis-aligned cube\n\t *\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction CubeCamera( near, far, cubeResolution ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'CubeCamera';\n\n\t\tvar fov = 90, aspect = 1;\n\n\t\tvar cameraPX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPX.up.set( 0, - 1, 0 );\n\t\tcameraPX.lookAt( new Vector3( 1, 0, 0 ) );\n\t\tthis.add( cameraPX );\n\n\t\tvar cameraNX = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNX.up.set( 0, - 1, 0 );\n\t\tcameraNX.lookAt( new Vector3( - 1, 0, 0 ) );\n\t\tthis.add( cameraNX );\n\n\t\tvar cameraPY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPY.up.set( 0, 0, 1 );\n\t\tcameraPY.lookAt( new Vector3( 0, 1, 0 ) );\n\t\tthis.add( cameraPY );\n\n\t\tvar cameraNY = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNY.up.set( 0, 0, - 1 );\n\t\tcameraNY.lookAt( new Vector3( 0, - 1, 0 ) );\n\t\tthis.add( cameraNY );\n\n\t\tvar cameraPZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraPZ.up.set( 0, - 1, 0 );\n\t\tcameraPZ.lookAt( new Vector3( 0, 0, 1 ) );\n\t\tthis.add( cameraPZ );\n\n\t\tvar cameraNZ = new PerspectiveCamera( fov, aspect, near, far );\n\t\tcameraNZ.up.set( 0, - 1, 0 );\n\t\tcameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );\n\t\tthis.add( cameraNZ );\n\n\t\tvar options = { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter };\n\n\t\tthis.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options );\n\n\t\tthis.updateCubeMap = function ( renderer, scene ) {\n\n\t\t\tif ( this.parent === null ) this.updateMatrixWorld();\n\n\t\t\tvar renderTarget = this.renderTarget;\n\t\t\tvar generateMipmaps = renderTarget.texture.generateMipmaps;\n\n\t\t\trenderTarget.texture.generateMipmaps = false;\n\n\t\t\trenderTarget.activeCubeFace = 0;\n\t\t\trenderer.render( scene, cameraPX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 1;\n\t\t\trenderer.render( scene, cameraNX, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 2;\n\t\t\trenderer.render( scene, cameraPY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 3;\n\t\t\trenderer.render( scene, cameraNY, renderTarget );\n\n\t\t\trenderTarget.activeCubeFace = 4;\n\t\t\trenderer.render( scene, cameraPZ, renderTarget );\n\n\t\t\trenderTarget.texture.generateMipmaps = generateMipmaps;\n\n\t\t\trenderTarget.activeCubeFace = 5;\n\t\t\trenderer.render( scene, cameraNZ, renderTarget );\n\n\t\t\trenderer.setRenderTarget( null );\n\n\t\t};\n\n\t}\n\n\tCubeCamera.prototype = Object.create( Object3D.prototype );\n\tCubeCamera.prototype.constructor = CubeCamera;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioListener() {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'AudioListener';\n\n\t\tthis.context = AudioContext.getContext();\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( this.context.destination );\n\n\t\tthis.filter = null;\n\n\t}\n\n\tAudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: AudioListener,\n\n\t\tgetInput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tremoveFilter: function ( ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\t\t\t\tthis.gain.connect( this.context.destination );\n\t\t\t\tthis.filter = null;\n\n\t\t\t}\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.filter;\n\n\t\t},\n\n\t\tsetFilter: function ( value ) {\n\n\t\t\tif ( this.filter !== null ) {\n\n\t\t\t\tthis.gain.disconnect( this.filter );\n\t\t\t\tthis.filter.disconnect( this.context.destination );\n\n\t\t\t} else {\n\n\t\t\t\tthis.gain.disconnect( this.context.destination );\n\n\t\t\t}\n\n\t\t\tthis.filter = value;\n\t\t\tthis.gain.connect( this.filter );\n\t\t\tthis.filter.connect( this.context.destination );\n\n\t\t},\n\n\t\tgetMasterVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\t\tsetMasterVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\t\t\tvar quaternion = new Quaternion();\n\t\t\tvar scale = new Vector3();\n\n\t\t\tvar orientation = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tvar listener = this.context.listener;\n\t\t\t\tvar up = this.up;\n\n\t\t\t\tthis.matrixWorld.decompose( position, quaternion, scale );\n\n\t\t\t\torientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );\n\n\t\t\t\tif ( listener.positionX ) {\n\n\t\t\t\t\tlistener.positionX.setValueAtTime( position.x, this.context.currentTime );\n\t\t\t\t\tlistener.positionY.setValueAtTime( position.y, this.context.currentTime );\n\t\t\t\t\tlistener.positionZ.setValueAtTime( position.z, this.context.currentTime );\n\t\t\t\t\tlistener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );\n\t\t\t\t\tlistener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );\n\t\t\t\t\tlistener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );\n\t\t\t\t\tlistener.upX.setValueAtTime( up.x, this.context.currentTime );\n\t\t\t\t\tlistener.upY.setValueAtTime( up.y, this.context.currentTime );\n\t\t\t\t\tlistener.upZ.setValueAtTime( up.z, this.context.currentTime );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tlistener.setPosition( position.x, position.y, position.z );\n\t\t\t\t\tlistener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t} )()\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Reece Aaron Lecrivain / http://reecenotes.com/\n\t */\n\n\tfunction Audio( listener ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.type = 'Audio';\n\n\t\tthis.context = listener.context;\n\n\t\tthis.gain = this.context.createGain();\n\t\tthis.gain.connect( listener.getInput() );\n\n\t\tthis.autoplay = false;\n\n\t\tthis.buffer = null;\n\t\tthis.loop = false;\n\t\tthis.startTime = 0;\n\t\tthis.playbackRate = 1;\n\t\tthis.isPlaying = false;\n\t\tthis.hasPlaybackControl = true;\n\t\tthis.sourceType = 'empty';\n\n\t\tthis.filters = [];\n\n\t}\n\n\tAudio.prototype = Object.assign( Object.create( Object3D.prototype ), {\n\n\t\tconstructor: Audio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.gain;\n\n\t\t},\n\n\t\tsetNodeSource: function ( audioNode ) {\n\n\t\t\tthis.hasPlaybackControl = false;\n\t\t\tthis.sourceType = 'audioNode';\n\t\t\tthis.source = audioNode;\n\t\t\tthis.connect();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetBuffer: function ( audioBuffer ) {\n\n\t\t\tthis.buffer = audioBuffer;\n\t\t\tthis.sourceType = 'buffer';\n\n\t\t\tif ( this.autoplay ) this.play();\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tplay: function () {\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: Audio is already playing.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvar source = this.context.createBufferSource();\n\n\t\t\tsource.buffer = this.buffer;\n\t\t\tsource.loop = this.loop;\n\t\t\tsource.onended = this.onEnded.bind( this );\n\t\t\tsource.playbackRate.setValueAtTime( this.playbackRate, this.startTime );\n\t\t\tsource.start( 0, this.startTime );\n\n\t\t\tthis.isPlaying = true;\n\n\t\t\tthis.source = source;\n\n\t\t\treturn this.connect();\n\n\t\t},\n\n\t\tpause: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = this.context.currentTime;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.source.stop();\n\t\t\tthis.startTime = 0;\n\t\t\tthis.isPlaying = false;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.connect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].connect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].connect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.connect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tdisconnect: function () {\n\n\t\t\tif ( this.filters.length > 0 ) {\n\n\t\t\t\tthis.source.disconnect( this.filters[ 0 ] );\n\n\t\t\t\tfor ( var i = 1, l = this.filters.length; i < l; i ++ ) {\n\n\t\t\t\t\tthis.filters[ i - 1 ].disconnect( this.filters[ i ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );\n\n\t\t\t} else {\n\n\t\t\t\tthis.source.disconnect( this.getOutput() );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilters: function () {\n\n\t\t\treturn this.filters;\n\n\t\t},\n\n\t\tsetFilters: function ( value ) {\n\n\t\t\tif ( ! value ) value = [];\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.disconnect();\n\t\t\t\tthis.filters = value;\n\t\t\t\tthis.connect();\n\n\t\t\t} else {\n\n\t\t\t\tthis.filters = value;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetFilter: function () {\n\n\t\t\treturn this.getFilters()[ 0 ];\n\n\t\t},\n\n\t\tsetFilter: function ( filter ) {\n\n\t\t\treturn this.setFilters( filter ? [ filter ] : [] );\n\n\t\t},\n\n\t\tsetPlaybackRate: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.playbackRate = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetPlaybackRate: function () {\n\n\t\t\treturn this.playbackRate;\n\n\t\t},\n\n\t\tonEnded: function () {\n\n\t\t\tthis.isPlaying = false;\n\n\t\t},\n\n\t\tgetLoop: function () {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn false;\n\n\t\t\t}\n\n\t\t\treturn this.loop;\n\n\t\t},\n\n\t\tsetLoop: function ( value ) {\n\n\t\t\tif ( this.hasPlaybackControl === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Audio: this Audio has no playback control.' );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tthis.loop = value;\n\n\t\t\tif ( this.isPlaying === true ) {\n\n\t\t\t\tthis.source.loop = this.loop;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetVolume: function () {\n\n\t\t\treturn this.gain.gain.value;\n\n\t\t},\n\n\n\t\tsetVolume: function ( value ) {\n\n\t\t\tthis.gain.gain.value = value;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PositionalAudio( listener ) {\n\n\t\tAudio.call( this, listener );\n\n\t\tthis.panner = this.context.createPanner();\n\t\tthis.panner.connect( this.gain );\n\n\t}\n\n\tPositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {\n\n\t\tconstructor: PositionalAudio,\n\n\t\tgetOutput: function () {\n\n\t\t\treturn this.panner;\n\n\t\t},\n\n\t\tgetRefDistance: function () {\n\n\t\t\treturn this.panner.refDistance;\n\n\t\t},\n\n\t\tsetRefDistance: function ( value ) {\n\n\t\t\tthis.panner.refDistance = value;\n\n\t\t},\n\n\t\tgetRolloffFactor: function () {\n\n\t\t\treturn this.panner.rolloffFactor;\n\n\t\t},\n\n\t\tsetRolloffFactor: function ( value ) {\n\n\t\t\tthis.panner.rolloffFactor = value;\n\n\t\t},\n\n\t\tgetDistanceModel: function () {\n\n\t\t\treturn this.panner.distanceModel;\n\n\t\t},\n\n\t\tsetDistanceModel: function ( value ) {\n\n\t\t\tthis.panner.distanceModel = value;\n\n\t\t},\n\n\t\tgetMaxDistance: function () {\n\n\t\t\treturn this.panner.maxDistance;\n\n\t\t},\n\n\t\tsetMaxDistance: function ( value ) {\n\n\t\t\tthis.panner.maxDistance = value;\n\n\t\t},\n\n\t\tupdateMatrixWorld: ( function () {\n\n\t\t\tvar position = new Vector3();\n\n\t\t\treturn function updateMatrixWorld( force ) {\n\n\t\t\t\tObject3D.prototype.updateMatrixWorld.call( this, force );\n\n\t\t\t\tposition.setFromMatrixPosition( this.matrixWorld );\n\n\t\t\t\tthis.panner.setPosition( position.x, position.y, position.z );\n\n\t\t\t};\n\n\t\t} )()\n\n\n\t} );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AudioAnalyser( audio, fftSize ) {\n\n\t\tthis.analyser = audio.context.createAnalyser();\n\t\tthis.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;\n\n\t\tthis.data = new Uint8Array( this.analyser.frequencyBinCount );\n\n\t\taudio.getOutput().connect( this.analyser );\n\n\t}\n\n\tObject.assign( AudioAnalyser.prototype, {\n\n\t\tgetFrequencyData: function () {\n\n\t\t\tthis.analyser.getByteFrequencyData( this.data );\n\n\t\t\treturn this.data;\n\n\t\t},\n\n\t\tgetAverageFrequency: function () {\n\n\t\t\tvar value = 0, data = this.getFrequencyData();\n\n\t\t\tfor ( var i = 0; i < data.length; i ++ ) {\n\n\t\t\t\tvalue += data[ i ];\n\n\t\t\t}\n\n\t\t\treturn value / data.length;\n\n\t\t}\n\n\t} );\n\n\t/**\n\t *\n\t * Buffered scene graph property that allows weighted accumulation.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyMixer( binding, typeName, valueSize ) {\n\n\t\tthis.binding = binding;\n\t\tthis.valueSize = valueSize;\n\n\t\tvar bufferType = Float64Array,\n\t\t\tmixFunction;\n\n\t\tswitch ( typeName ) {\n\n\t\t\tcase 'quaternion':\n\t\t\t\tmixFunction = this._slerp;\n\t\t\t\tbreak;\n\n\t\t\tcase 'string':\n\t\t\tcase 'bool':\n\t\t\t\tbufferType = Array;\n\t\t\t\tmixFunction = this._select;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tmixFunction = this._lerp;\n\n\t\t}\n\n\t\tthis.buffer = new bufferType( valueSize * 4 );\n\t\t// layout: [ incoming | accu0 | accu1 | orig ]\n\t\t//\n\t\t// interpolators can use .buffer as their .result\n\t\t// the data then goes to 'incoming'\n\t\t//\n\t\t// 'accu0' and 'accu1' are used frame-interleaved for\n\t\t// the cumulative result and are compared to detect\n\t\t// changes\n\t\t//\n\t\t// 'orig' stores the original state of the property\n\n\t\tthis._mixBufferRegion = mixFunction;\n\n\t\tthis.cumulativeWeight = 0;\n\n\t\tthis.useCount = 0;\n\t\tthis.referenceCount = 0;\n\n\t}\n\n\tPropertyMixer.prototype = {\n\n\t\tconstructor: PropertyMixer,\n\n\t\t// accumulate data in the 'incoming' region into 'accu'\n\t\taccumulate: function( accuIndex, weight ) {\n\n\t\t\t// note: happily accumulating nothing when weight = 0, the caller knows\n\t\t\t// the weight and shouldn't have made the call in the first place\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tcurrentWeight = this.cumulativeWeight;\n\n\t\t\tif ( currentWeight === 0 ) {\n\n\t\t\t\t// accuN := incoming * weight\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset + i ] = buffer[ i ];\n\n\t\t\t\t}\n\n\t\t\t\tcurrentWeight = weight;\n\n\t\t\t} else {\n\n\t\t\t\t// accuN := accuN + incoming * weight\n\n\t\t\t\tcurrentWeight += weight;\n\t\t\t\tvar mix = weight / currentWeight;\n\t\t\t\tthis._mixBufferRegion( buffer, offset, 0, mix, stride );\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = currentWeight;\n\n\t\t},\n\n\t\t// apply the state of 'accu' to the binding when accus differ\n\t\tapply: function( accuIndex ) {\n\n\t\t\tvar stride = this.valueSize,\n\t\t\t\tbuffer = this.buffer,\n\t\t\t\toffset = accuIndex * stride + stride,\n\n\t\t\t\tweight = this.cumulativeWeight,\n\n\t\t\t\tbinding = this.binding;\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t\tif ( weight < 1 ) {\n\n\t\t\t\t// accuN := accuN + original * ( 1 - cumulativeWeight )\n\n\t\t\t\tvar originalValueOffset = stride * 3;\n\n\t\t\t\tthis._mixBufferRegion(\n\t\t\t\t\t\tbuffer, offset, originalValueOffset, 1 - weight, stride );\n\n\t\t\t}\n\n\t\t\tfor ( var i = stride, e = stride + stride; i !== e; ++ i ) {\n\n\t\t\t\tif ( buffer[ i ] !== buffer[ i + stride ] ) {\n\n\t\t\t\t\t// value has changed -> update scene graph\n\n\t\t\t\t\tbinding.setValue( buffer, offset );\n\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remember the state of the bound property and copy it to both accus\n\t\tsaveOriginalState: function() {\n\n\t\t\tvar binding = this.binding;\n\n\t\t\tvar buffer = this.buffer,\n\t\t\t\tstride = this.valueSize,\n\n\t\t\t\toriginalValueOffset = stride * 3;\n\n\t\t\tbinding.getValue( buffer, originalValueOffset );\n\n\t\t\t// accu[0..1] := orig -- initially detect changes against the original\n\t\t\tfor ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {\n\n\t\t\t\tbuffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];\n\n\t\t\t}\n\n\t\t\tthis.cumulativeWeight = 0;\n\n\t\t},\n\n\t\t// apply the state previously taken via 'saveOriginalState' to the binding\n\t\trestoreOriginalState: function() {\n\n\t\t\tvar originalValueOffset = this.valueSize * 3;\n\t\t\tthis.binding.setValue( this.buffer, originalValueOffset );\n\n\t\t},\n\n\n\t\t// mix functions\n\n\t\t_select: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tif ( t >= 0.5 ) {\n\n\t\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\t\tbuffer[ dstOffset + i ] = buffer[ srcOffset + i ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_slerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tQuaternion.slerpFlat( buffer, dstOffset,\n\t\t\t\t\tbuffer, dstOffset, buffer, srcOffset, t );\n\n\t\t},\n\n\t\t_lerp: function( buffer, dstOffset, srcOffset, t, stride ) {\n\n\t\t\tvar s = 1 - t;\n\n\t\t\tfor ( var i = 0; i !== stride; ++ i ) {\n\n\t\t\t\tvar j = dstOffset + i;\n\n\t\t\t\tbuffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * A reference to a real property in the scene graph.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction PropertyBinding( rootNode, path, parsedPath ) {\n\n\t\tthis.path = path;\n\t\tthis.parsedPath = parsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis.node = PropertyBinding.findNode(\n\t\t\t\trootNode, this.parsedPath.nodeName ) || rootNode;\n\n\t\tthis.rootNode = rootNode;\n\n\t}\n\n\tPropertyBinding.prototype = {\n\n\t\tconstructor: PropertyBinding,\n\n\t\tgetValue: function getValue_unbound( targetArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.getValue( targetArray, offset );\n\n\t\t\t// Note: This class uses a State pattern on a per-method basis:\n\t\t\t// 'bind' sets 'this.getValue' / 'setValue' and shadows the\n\t\t\t// prototype version of these methods with one that represents\n\t\t\t// the bound state. When the property is not found, the methods\n\t\t\t// become no-ops.\n\n\t\t},\n\n\t\tsetValue: function getValue_unbound( sourceArray, offset ) {\n\n\t\t\tthis.bind();\n\t\t\tthis.setValue( sourceArray, offset );\n\n\t\t},\n\n\t\t// create getter / setter pair for a property in the scene graph\n\t\tbind: function() {\n\n\t\t\tvar targetObject = this.node,\n\t\t\t\tparsedPath = this.parsedPath,\n\n\t\t\t\tobjectName = parsedPath.objectName,\n\t\t\t\tpropertyName = parsedPath.propertyName,\n\t\t\t\tpropertyIndex = parsedPath.propertyIndex;\n\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\ttargetObject = PropertyBinding.findNode(\n\t\t\t\t\t\tthis.rootNode, parsedPath.nodeName ) || this.rootNode;\n\n\t\t\t\tthis.node = targetObject;\n\n\t\t\t}\n\n\t\t\t// set fail state so we can just 'return' on error\n\t\t\tthis.getValue = this._getValue_unavailable;\n\t\t\tthis.setValue = this._setValue_unavailable;\n\n\t \t\t// ensure there is a value node\n\t\t\tif ( ! targetObject ) {\n\n\t\t\t\tconsole.error( \" trying to update node for track: \" + this.path + \" but it wasn't found.\" );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tif ( objectName ) {\n\n\t\t\t\tvar objectIndex = parsedPath.objectIndex;\n\n\t\t\t\t// special cases were we need to reach deeper into the hierarchy to get the face materials....\n\t\t\t\tswitch ( objectName ) {\n\n\t\t\t\t\tcase 'materials':\n\n\t\t\t\t\t\tif ( ! targetObject.material ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material as node does not have a material', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! targetObject.material.materials ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to material.materials as node.material does not have a materials array', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject.material.materials;\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'bones':\n\n\t\t\t\t\t\tif ( ! targetObject.skeleton ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to bones as node does not have a skeleton', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// potential future optimization: skip this if propertyIndex is already an integer\n\t\t\t\t\t\t// and convert the integer string to a true integer.\n\n\t\t\t\t\t\ttargetObject = targetObject.skeleton.bones;\n\n\t\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\t\tfor ( var i = 0; i < targetObject.length; i ++ ) {\n\n\t\t\t\t\t\t\tif ( targetObject[ i ].name === objectIndex ) {\n\n\t\t\t\t\t\t\t\tobjectIndex = i;\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\n\t\t\t\t\t\tif ( targetObject[ objectName ] === undefined ) {\n\n\t\t\t\t\t\t\tconsole.error( ' can not bind to objectName of node, undefined', this );\n\t\t\t\t\t\t\treturn;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetObject = targetObject[ objectName ];\n\n\t\t\t\t}\n\n\n\t\t\t\tif ( objectIndex !== undefined ) {\n\n\t\t\t\t\tif ( targetObject[ objectIndex ] === undefined ) {\n\n\t\t\t\t\t\tconsole.error( \" trying to bind to objectIndex of objectName, but is undefined:\", this, targetObject );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\ttargetObject = targetObject[ objectIndex ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// resolve property\n\t\t\tvar nodeProperty = targetObject[ propertyName ];\n\n\t\t\tif ( nodeProperty === undefined ) {\n\n\t\t\t\tvar nodeName = parsedPath.nodeName;\n\n\t\t\t\tconsole.error( \" trying to update property for track: \" + nodeName +\n\t\t\t\t\t\t'.' + propertyName + \" but it wasn't found.\", targetObject );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// determine versioning scheme\n\t\t\tvar versioning = this.Versioning.None;\n\n\t\t\tif ( targetObject.needsUpdate !== undefined ) { // material\n\n\t\t\t\tversioning = this.Versioning.NeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform\n\n\t\t\t\tversioning = this.Versioning.MatrixWorldNeedsUpdate;\n\t\t\t\tthis.targetObject = targetObject;\n\n\t\t\t}\n\n\t\t\t// determine how the property gets bound\n\t\t\tvar bindingType = this.BindingType.Direct;\n\n\t\t\tif ( propertyIndex !== undefined ) {\n\t\t\t\t// access a sub element of the property array (only primitives are supported right now)\n\n\t\t\t\tif ( propertyName === \"morphTargetInfluences\" ) {\n\t\t\t\t\t// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.\n\n\t\t\t\t\t// support resolving morphTarget names into indices.\n\t\t\t\t\tif ( ! targetObject.geometry ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( ! targetObject.geometry.morphTargets ) {\n\n\t\t\t\t\t\tconsole.error( ' can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets', this );\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( var i = 0; i < this.node.geometry.morphTargets.length; i ++ ) {\n\n\t\t\t\t\t\tif ( targetObject.geometry.morphTargets[ i ].name === propertyIndex ) {\n\n\t\t\t\t\t\t\tpropertyIndex = i;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tbindingType = this.BindingType.ArrayElement;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\t\t\t\tthis.propertyIndex = propertyIndex;\n\n\t\t\t} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {\n\t\t\t\t// must use copy for Object3D.Euler/Quaternion\n\n\t\t\t\tbindingType = this.BindingType.HasFromToArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else if ( nodeProperty.length !== undefined ) {\n\n\t\t\t\tbindingType = this.BindingType.EntireArray;\n\n\t\t\t\tthis.resolvedProperty = nodeProperty;\n\n\t\t\t} else {\n\n\t\t\t\tthis.propertyName = propertyName;\n\n\t\t\t}\n\n\t\t\t// select getter / setter\n\t\t\tthis.getValue = this.GetterByBindingType[ bindingType ];\n\t\t\tthis.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tthis.node = null;\n\n\t\t\t// back to the prototype version of getValue / setValue\n\t\t\t// note: avoiding to mutate the shape of 'this' via 'delete'\n\t\t\tthis.getValue = this._getValue_unbound;\n\t\t\tthis.setValue = this._setValue_unbound;\n\n\t\t}\n\n\t};\n\n\tObject.assign( PropertyBinding.prototype, { // prototype, continued\n\n\t\t// these are used to \"bind\" a nonexistent property\n\t\t_getValue_unavailable: function() {},\n\t\t_setValue_unavailable: function() {},\n\n\t\t// initial state of these methods that calls 'bind'\n\t\t_getValue_unbound: PropertyBinding.prototype.getValue,\n\t\t_setValue_unbound: PropertyBinding.prototype.setValue,\n\n\t\tBindingType: {\n\t\t\tDirect: 0,\n\t\t\tEntireArray: 1,\n\t\t\tArrayElement: 2,\n\t\t\tHasFromToArray: 3\n\t\t},\n\n\t\tVersioning: {\n\t\t\tNone: 0,\n\t\t\tNeedsUpdate: 1,\n\t\t\tMatrixWorldNeedsUpdate: 2\n\t\t},\n\n\t\tGetterByBindingType: [\n\n\t\t\tfunction getValue_direct( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.node[ this.propertyName ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_array( buffer, offset ) {\n\n\t\t\t\tvar source = this.resolvedProperty;\n\n\t\t\t\tfor ( var i = 0, n = source.length; i !== n; ++ i ) {\n\n\t\t\t\t\tbuffer[ offset ++ ] = source[ i ];\n\n\t\t\t\t}\n\n\t\t\t},\n\n\t\t\tfunction getValue_arrayElement( buffer, offset ) {\n\n\t\t\t\tbuffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];\n\n\t\t\t},\n\n\t\t\tfunction getValue_toArray( buffer, offset ) {\n\n\t\t\t\tthis.resolvedProperty.toArray( buffer, offset );\n\n\t\t\t}\n\n\t\t],\n\n\t\tSetterByBindingTypeAndVersioning: [\n\n\t\t\t[\n\t\t\t\t// Direct\n\n\t\t\t\tfunction setValue_direct( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.node[ this.propertyName ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// EntireArray\n\n\t\t\t\tfunction setValue_array( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tvar dest = this.resolvedProperty;\n\n\t\t\t\t\tfor ( var i = 0, n = dest.length; i !== n; ++ i ) {\n\n\t\t\t\t\t\tdest[ i ] = buffer[ offset ++ ];\n\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// ArrayElement\n\n\t\t\t\tfunction setValue_arrayElement( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t], [\n\n\t\t\t\t// HasToFromArray\n\n\t\t\t\tfunction setValue_fromArray( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.needsUpdate = true;\n\n\t\t\t\t},\n\n\t\t\t\tfunction setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {\n\n\t\t\t\t\tthis.resolvedProperty.fromArray( buffer, offset );\n\t\t\t\t\tthis.targetObject.matrixWorldNeedsUpdate = true;\n\n\t\t\t\t}\n\n\t\t\t]\n\n\t\t]\n\n\t} );\n\n\tPropertyBinding.Composite =\n\t\t\tfunction( targetGroup, path, optionalParsedPath ) {\n\n\t\tvar parsedPath = optionalParsedPath ||\n\t\t\t\tPropertyBinding.parseTrackName( path );\n\n\t\tthis._targetGroup = targetGroup;\n\t\tthis._bindings = targetGroup.subscribe_( path, parsedPath );\n\n\t};\n\n\tPropertyBinding.Composite.prototype = {\n\n\t\tconstructor: PropertyBinding.Composite,\n\n\t\tgetValue: function( array, offset ) {\n\n\t\t\tthis.bind(); // bind all binding\n\n\t\t\tvar firstValidIndex = this._targetGroup.nCachedObjects_,\n\t\t\t\tbinding = this._bindings[ firstValidIndex ];\n\n\t\t\t// and only call .getValue on the first\n\t\t\tif ( binding !== undefined ) binding.getValue( array, offset );\n\n\t\t},\n\n\t\tsetValue: function( array, offset ) {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].setValue( array, offset );\n\n\t\t\t}\n\n\t\t},\n\n\t\tbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].bind();\n\n\t\t\t}\n\n\t\t},\n\n\t\tunbind: function() {\n\n\t\t\tvar bindings = this._bindings;\n\n\t\t\tfor ( var i = this._targetGroup.nCachedObjects_,\n\t\t\t\t\tn = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tbindings[ i ].unbind();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.create = function( root, path, parsedPath ) {\n\n\t\tif ( ! ( root && root.isAnimationObjectGroup ) ) {\n\n\t\t\treturn new PropertyBinding( root, path, parsedPath );\n\n\t\t} else {\n\n\t\t\treturn new PropertyBinding.Composite( root, path, parsedPath );\n\n\t\t}\n\n\t};\n\n\tPropertyBinding.parseTrackName = function( trackName ) {\n\n\t\t// matches strings in the form of:\n\t\t// nodeName.property\n\t\t// nodeName.property[accessor]\n\t\t// nodeName.material.property[accessor]\n\t\t// uuid.property[accessor]\n\t\t// uuid.objectName[objectIndex].propertyName[propertyIndex]\n\t\t// parentName/nodeName.property\n\t\t// parentName/parentName/nodeName.property[index]\n\t\t// .bone[Armature.DEF_cog].position\n\t\t// scene:helium_balloon_model:helium_balloon_model.position\n\t\t// created and tested via https://regex101.com/#javascript\n\n\t\tvar re = /^((?:[\\w-]+[\\/:])*)([\\w-]+)?(?:\\.([\\w-]+)(?:\\[(.+)\\])?)?\\.([\\w-]+)(?:\\[(.+)\\])?$/;\n\t\tvar matches = re.exec( trackName );\n\n\t\tif ( ! matches ) {\n\n\t\t\tthrow new Error( \"cannot parse trackName at all: \" + trackName );\n\n\t\t}\n\n\t\tvar results = {\n\t\t\t// directoryName: matches[ 1 ], // (tschw) currently unused\n\t\t\tnodeName: matches[ 2 ], \t// allowed to be null, specified root node.\n\t\t\tobjectName: matches[ 3 ],\n\t\t\tobjectIndex: matches[ 4 ],\n\t\t\tpropertyName: matches[ 5 ],\n\t\t\tpropertyIndex: matches[ 6 ]\t// allowed to be null, specifies that the whole property is set.\n\t\t};\n\n\t\tif ( results.propertyName === null || results.propertyName.length === 0 ) {\n\n\t\t\tthrow new Error( \"can not parse propertyName from trackName: \" + trackName );\n\n\t\t}\n\n\t\treturn results;\n\n\t};\n\n\tPropertyBinding.findNode = function( root, nodeName ) {\n\n\t\tif ( ! nodeName || nodeName === \"\" || nodeName === \"root\" || nodeName === \".\" || nodeName === -1 || nodeName === root.name || nodeName === root.uuid ) {\n\n\t\t\treturn root;\n\n\t\t}\n\n\t\t// search into skeleton bones.\n\t\tif ( root.skeleton ) {\n\n\t\t\tvar searchSkeleton = function( skeleton ) {\n\n\t\t\t\tfor( var i = 0; i < skeleton.bones.length; i ++ ) {\n\n\t\t\t\t\tvar bone = skeleton.bones[ i ];\n\n\t\t\t\t\tif ( bone.name === nodeName ) {\n\n\t\t\t\t\t\treturn bone;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar bone = searchSkeleton( root.skeleton );\n\n\t\t\tif ( bone ) {\n\n\t\t\t\treturn bone;\n\n\t\t\t}\n\t\t}\n\n\t\t// search into node subtree.\n\t\tif ( root.children ) {\n\n\t\t\tvar searchNodeSubtree = function( children ) {\n\n\t\t\t\tfor( var i = 0; i < children.length; i ++ ) {\n\n\t\t\t\t\tvar childNode = children[ i ];\n\n\t\t\t\t\tif ( childNode.name === nodeName || childNode.uuid === nodeName ) {\n\n\t\t\t\t\t\treturn childNode;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result = searchNodeSubtree( childNode.children );\n\n\t\t\t\t\tif ( result ) return result;\n\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\n\t\t\t};\n\n\t\t\tvar subTreeNode = searchNodeSubtree( root.children );\n\n\t\t\tif ( subTreeNode ) {\n\n\t\t\t\treturn subTreeNode;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn null;\n\n\t};\n\n\t/**\n\t *\n\t * A group of objects that receives a shared animation state.\n\t *\n\t * Usage:\n\t *\n\t * \t-\tAdd objects you would otherwise pass as 'root' to the\n\t * \t\tconstructor or the .clipAction method of AnimationMixer.\n\t *\n\t * \t-\tInstead pass this object as 'root'.\n\t *\n\t * \t-\tYou can also add and remove objects later when the mixer\n\t * \t\tis running.\n\t *\n\t * Note:\n\t *\n\t * \tObjects of this class appear as one object to the mixer,\n\t * \tso cache control of the individual objects must be done\n\t * \ton the group.\n\t *\n\t * Limitation:\n\t *\n\t * \t- \tThe animated properties must be compatible among the\n\t * \t\tall objects in the group.\n\t *\n\t * -\tA single property can either be controlled through a\n\t * \ttarget group or directly, but not both.\n\t *\n\t * @author tschw\n\t */\n\n\tfunction AnimationObjectGroup( var_args ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\t// cached objects followed by the active ones\n\t\tthis._objects = Array.prototype.slice.call( arguments );\n\n\t\tthis.nCachedObjects_ = 0;\t\t\t// threshold\n\t\t// note: read by PropertyBinding.Composite\n\n\t\tvar indices = {};\n\t\tthis._indicesByUUID = indices;\t\t// for bookkeeping\n\n\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\tindices[ arguments[ i ].uuid ] = i;\n\n\t\t}\n\n\t\tthis._paths = [];\t\t\t\t\t// inside: string\n\t\tthis._parsedPaths = [];\t\t\t\t// inside: { we don't care, here }\n\t\tthis._bindings = []; \t\t\t\t// inside: Array< PropertyBinding >\n\t\tthis._bindingsIndicesByPath = {}; \t// inside: indices in these arrays\n\n\t\tvar scope = this;\n\n\t\tthis.stats = {\n\n\t\t\tobjects: {\n\t\t\t\tget total() { return scope._objects.length; },\n\t\t\t\tget inUse() { return this.total - scope.nCachedObjects_; }\n\t\t\t},\n\n\t\t\tget bindingsPerObject() { return scope._bindings.length; }\n\n\t\t};\n\n\t}\n\n\tAnimationObjectGroup.prototype = {\n\n\t\tconstructor: AnimationObjectGroup,\n\n\t\tisAnimationObjectGroup: true,\n\n\t\tadd: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tpaths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ],\n\t\t\t\t\tknownObject = undefined;\n\n\t\t\t\tif ( index === undefined ) {\n\n\t\t\t\t\t// unknown object -> add it to the ACTIVE region\n\n\t\t\t\t\tindex = nObjects ++;\n\t\t\t\t\tindicesByUUID[ uuid ] = index;\n\t\t\t\t\tobjects.push( object );\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tbindings[ j ].push(\n\t\t\t\t\t\t\t\tnew PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( index < nCachedObjects ) {\n\n\t\t\t\t\tknownObject = objects[ index ];\n\n\t\t\t\t\t// move existing object to the ACTIVE region\n\n\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ];\n\n\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = firstActiveIndex;\n\t\t\t\t\tobjects[ firstActiveIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\n\t\t\t\t\t\tif ( binding === undefined ) {\n\n\t\t\t\t\t\t\t// since we do not bother to create new bindings\n\t\t\t\t\t\t\t// for objects that are cached, the binding may\n\t\t\t\t\t\t\t// or may not exist\n\n\t\t\t\t\t\t\tbinding = new PropertyBinding(\n\t\t\t\t\t\t\t\t\tobject, paths[ j ], parsedPaths[ j ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( objects[ index ] !== knownObject) {\n\n\t\t\t\t\tconsole.error( \"Different objects with the same UUID \" +\n\t\t\t\t\t\t\t\"detected. Clean the caches or recreate your \" +\n\t\t\t\t\t\t\t\"infrastructure when reloading scenes...\" );\n\n\t\t\t\t} // else the object is already where we want it to be\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\tremove: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined && index >= nCachedObjects ) {\n\n\t\t\t\t\t// move existing object into the CACHED region\n\n\t\t\t\t\tvar lastCachedIndex = nCachedObjects ++,\n\t\t\t\t\t\tfirstActiveObject = objects[ lastCachedIndex ];\n\n\t\t\t\t\tindicesByUUID[ firstActiveObject.uuid ] = index;\n\t\t\t\t\tobjects[ index ] = firstActiveObject;\n\n\t\t\t\t\tindicesByUUID[ uuid ] = lastCachedIndex;\n\t\t\t\t\tobjects[ lastCachedIndex ] = object;\n\n\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\tfirstActive = bindingsForPath[ lastCachedIndex ],\n\t\t\t\t\t\t\tbinding = bindingsForPath[ index ];\n\n\t\t\t\t\t\tbindingsForPath[ index ] = firstActive;\n\t\t\t\t\t\tbindingsForPath[ lastCachedIndex ] = binding;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// remove & forget\n\t\tuncache: function( var_args ) {\n\n\t\t\tvar objects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tindicesByUUID = this._indicesByUUID,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = bindings.length;\n\n\t\t\tfor ( var i = 0, n = arguments.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = arguments[ i ],\n\t\t\t\t\tuuid = object.uuid,\n\t\t\t\t\tindex = indicesByUUID[ uuid ];\n\n\t\t\t\tif ( index !== undefined ) {\n\n\t\t\t\t\tdelete indicesByUUID[ uuid ];\n\n\t\t\t\t\tif ( index < nCachedObjects ) {\n\n\t\t\t\t\t\t// object is cached, shrink the CACHED region\n\n\t\t\t\t\t\tvar firstActiveIndex = -- nCachedObjects,\n\t\t\t\t\t\t\tlastCachedObject = objects[ firstActiveIndex ],\n\t\t\t\t\t\t\tlastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\t// last cached object takes this object's place\n\t\t\t\t\t\tindicesByUUID[ lastCachedObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastCachedObject;\n\n\t\t\t\t\t\t// last object goes to the activated slot and pop\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = firstActiveIndex;\n\t\t\t\t\t\tobjects[ firstActiveIndex ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ],\n\t\t\t\t\t\t\t\tlastCached = bindingsForPath[ firstActiveIndex ],\n\t\t\t\t\t\t\t\tlast = bindingsForPath[ lastIndex ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = lastCached;\n\t\t\t\t\t\t\tbindingsForPath[ firstActiveIndex ] = last;\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// object is active, just swap with the last and pop\n\n\t\t\t\t\t\tvar lastIndex = -- nObjects,\n\t\t\t\t\t\t\tlastObject = objects[ lastIndex ];\n\n\t\t\t\t\t\tindicesByUUID[ lastObject.uuid ] = index;\n\t\t\t\t\t\tobjects[ index ] = lastObject;\n\t\t\t\t\t\tobjects.pop();\n\n\t\t\t\t\t\t// accounting is done, now do the same for all bindings\n\n\t\t\t\t\t\tfor ( var j = 0, m = nBindings; j !== m; ++ j ) {\n\n\t\t\t\t\t\t\tvar bindingsForPath = bindings[ j ];\n\n\t\t\t\t\t\t\tbindingsForPath[ index ] = bindingsForPath[ lastIndex ];\n\t\t\t\t\t\t\tbindingsForPath.pop();\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // cached or active\n\n\t\t\t\t} // if object is known\n\n\t\t\t} // for arguments\n\n\t\t\tthis.nCachedObjects_ = nCachedObjects;\n\n\t\t},\n\n\t\t// Internal interface used by befriended PropertyBinding.Composite:\n\n\t\tsubscribe_: function( path, parsedPath ) {\n\t\t\t// returns an array of bindings for the given path that is changed\n\t\t\t// according to the contained objects in the group\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ],\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( index !== undefined ) return bindings[ index ];\n\n\t\t\tvar paths = this._paths,\n\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\tobjects = this._objects,\n\t\t\t\tnObjects = objects.length,\n\t\t\t\tnCachedObjects = this.nCachedObjects_,\n\t\t\t\tbindingsForPath = new Array( nObjects );\n\n\t\t\tindex = bindings.length;\n\n\t\t\tindicesByPath[ path ] = index;\n\n\t\t\tpaths.push( path );\n\t\t\tparsedPaths.push( parsedPath );\n\t\t\tbindings.push( bindingsForPath );\n\n\t\t\tfor ( var i = nCachedObjects,\n\t\t\t\t\tn = objects.length; i !== n; ++ i ) {\n\n\t\t\t\tvar object = objects[ i ];\n\n\t\t\t\tbindingsForPath[ i ] =\n\t\t\t\t\t\tnew PropertyBinding( object, path, parsedPath );\n\n\t\t\t}\n\n\t\t\treturn bindingsForPath;\n\n\t\t},\n\n\t\tunsubscribe_: function( path ) {\n\t\t\t// tells the group to forget about a property path and no longer\n\t\t\t// update the array previously obtained with 'subscribe_'\n\n\t\t\tvar indicesByPath = this._bindingsIndicesByPath,\n\t\t\t\tindex = indicesByPath[ path ];\n\n\t\t\tif ( index !== undefined ) {\n\n\t\t\t\tvar paths = this._paths,\n\t\t\t\t\tparsedPaths = this._parsedPaths,\n\t\t\t\t\tbindings = this._bindings,\n\t\t\t\t\tlastBindingsIndex = bindings.length - 1,\n\t\t\t\t\tlastBindings = bindings[ lastBindingsIndex ],\n\t\t\t\t\tlastBindingsPath = path[ lastBindingsIndex ];\n\n\t\t\t\tindicesByPath[ lastBindingsPath ] = index;\n\n\t\t\t\tbindings[ index ] = lastBindings;\n\t\t\t\tbindings.pop();\n\n\t\t\t\tparsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];\n\t\t\t\tparsedPaths.pop();\n\n\t\t\t\tpaths[ index ] = paths[ lastBindingsIndex ];\n\t\t\t\tpaths.pop();\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Action provided by AnimationMixer for scheduling clip playback on specific\n\t * objects.\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t *\n\t */\n\n\tfunction AnimationAction( mixer, clip, localRoot ) {\n\n\t\tthis._mixer = mixer;\n\t\tthis._clip = clip;\n\t\tthis._localRoot = localRoot || null;\n\n\t\tvar tracks = clip.tracks,\n\t\t\tnTracks = tracks.length,\n\t\t\tinterpolants = new Array( nTracks );\n\n\t\tvar interpolantSettings = {\n\t\t\t\tendingStart: \tZeroCurvatureEnding,\n\t\t\t\tendingEnd:\t\tZeroCurvatureEnding\n\t\t};\n\n\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\tvar interpolant = tracks[ i ].createInterpolant( null );\n\t\t\tinterpolants[ i ] = interpolant;\n\t\t\tinterpolant.settings = interpolantSettings;\n\n\t\t}\n\n\t\tthis._interpolantSettings = interpolantSettings;\n\n\t\tthis._interpolants = interpolants;\t// bound by the mixer\n\n\t\t// inside: PropertyMixer (managed by the mixer)\n\t\tthis._propertyBindings = new Array( nTracks );\n\n\t\tthis._cacheIndex = null;\t\t\t// for the memory manager\n\t\tthis._byClipCacheIndex = null;\t\t// for the memory manager\n\n\t\tthis._timeScaleInterpolant = null;\n\t\tthis._weightInterpolant = null;\n\n\t\tthis.loop = LoopRepeat;\n\t\tthis._loopCount = -1;\n\n\t\t// global mixer time when the action is to be started\n\t\t// it's set back to 'null' upon start of the action\n\t\tthis._startTime = null;\n\n\t\t// scaled local time of the action\n\t\t// gets clamped or wrapped to 0..clip.duration according to loop\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1;\n\t\tthis._effectiveTimeScale = 1;\n\n\t\tthis.weight = 1;\n\t\tthis._effectiveWeight = 1;\n\n\t\tthis.repetitions = Infinity; \t\t// no. of repetitions when looping\n\n\t\tthis.paused = false;\t\t\t\t// false -> zero effective time scale\n\t\tthis.enabled = true;\t\t\t\t// true -> zero effective weight\n\n\t\tthis.clampWhenFinished \t= false;\t// keep feeding the last frame?\n\n\t\tthis.zeroSlopeAtStart \t= true;\t\t// for smooth interpolation w/o separate\n\t\tthis.zeroSlopeAtEnd\t\t= true;\t\t// clips for start, loop and end\n\n\t}\n\n\tAnimationAction.prototype = {\n\n\t\tconstructor: AnimationAction,\n\n\t\t// State & Scheduling\n\n\t\tplay: function() {\n\n\t\t\tthis._mixer._activateAction( this );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstop: function() {\n\n\t\t\tthis._mixer._deactivateAction( this );\n\n\t\t\treturn this.reset();\n\n\t\t},\n\n\t\treset: function() {\n\n\t\t\tthis.paused = false;\n\t\t\tthis.enabled = true;\n\n\t\t\tthis.time = 0;\t\t\t// restart clip\n\t\t\tthis._loopCount = -1;\t// forget previous loops\n\t\t\tthis._startTime = null;\t// forget scheduling\n\n\t\t\treturn this.stopFading().stopWarping();\n\n\t\t},\n\n\t\tisRunning: function() {\n\n\t\t\treturn this.enabled && ! this.paused && this.timeScale !== 0 &&\n\t\t\t\t\tthis._startTime === null && this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\t// return true when play has been called\n\t\tisScheduled: function() {\n\n\t\t\treturn this._mixer._isActiveAction( this );\n\n\t\t},\n\n\t\tstartAt: function( time ) {\n\n\t\t\tthis._startTime = time;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetLoop: function( mode, repetitions ) {\n\n\t\t\tthis.loop = mode;\n\t\t\tthis.repetitions = repetitions;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Weight\n\n\t\t// set the weight stopping any scheduled fading\n\t\t// although .enabled = false yields an effective weight of zero, this\n\t\t// method does *not* change .enabled, because it would be confusing\n\t\tsetEffectiveWeight: function( weight ) {\n\n\t\t\tthis.weight = weight;\n\n\t\t\t// note: same logic as when updated at runtime\n\t\t\tthis._effectiveWeight = this.enabled ? weight : 0;\n\n\t\t\treturn this.stopFading();\n\n\t\t},\n\n\t\t// return the weight considering fading and .enabled\n\t\tgetEffectiveWeight: function() {\n\n\t\t\treturn this._effectiveWeight;\n\n\t\t},\n\n\t\tfadeIn: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 0, 1 );\n\n\t\t},\n\n\t\tfadeOut: function( duration ) {\n\n\t\t\treturn this._scheduleFading( duration, 1, 0 );\n\n\t\t},\n\n\t\tcrossFadeFrom: function( fadeOutAction, duration, warp ) {\n\n\t\t\tfadeOutAction.fadeOut( duration );\n\t\t\tthis.fadeIn( duration );\n\n\t\t\tif( warp ) {\n\n\t\t\t\tvar fadeInDuration = this._clip.duration,\n\t\t\t\t\tfadeOutDuration = fadeOutAction._clip.duration,\n\n\t\t\t\t\tstartEndRatio = fadeOutDuration / fadeInDuration,\n\t\t\t\t\tendStartRatio = fadeInDuration / fadeOutDuration;\n\n\t\t\t\tfadeOutAction.warp( 1.0, startEndRatio, duration );\n\t\t\t\tthis.warp( endStartRatio, 1.0, duration );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcrossFadeTo: function( fadeInAction, duration, warp ) {\n\n\t\t\treturn fadeInAction.crossFadeFrom( this, duration, warp );\n\n\t\t},\n\n\t\tstopFading: function() {\n\n\t\t\tvar weightInterpolant = this._weightInterpolant;\n\n\t\t\tif ( weightInterpolant !== null ) {\n\n\t\t\t\tthis._weightInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( weightInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Time Scale Control\n\n\t\t// set the weight stopping any scheduled warping\n\t\t// although .paused = true yields an effective time scale of zero, this\n\t\t// method does *not* change .paused, because it would be confusing\n\t\tsetEffectiveTimeScale: function( timeScale ) {\n\n\t\t\tthis.timeScale = timeScale;\n\t\t\tthis._effectiveTimeScale = this.paused ? 0 :timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\t// return the time scale considering warping and .paused\n\t\tgetEffectiveTimeScale: function() {\n\n\t\t\treturn this._effectiveTimeScale;\n\n\t\t},\n\n\t\tsetDuration: function( duration ) {\n\n\t\t\tthis.timeScale = this._clip.duration / duration;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\tsyncWith: function( action ) {\n\n\t\t\tthis.time = action.time;\n\t\t\tthis.timeScale = action.timeScale;\n\n\t\t\treturn this.stopWarping();\n\n\t\t},\n\n\t\thalt: function( duration ) {\n\n\t\t\treturn this.warp( this._effectiveTimeScale, 0, duration );\n\n\t\t},\n\n\t\twarp: function( startTimeScale, endTimeScale, duration ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._timeScaleInterpolant,\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._timeScaleInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now;\n\t\t\ttimes[ 1 ] = now + duration;\n\n\t\t\tvalues[ 0 ] = startTimeScale / timeScale;\n\t\t\tvalues[ 1 ] = endTimeScale / timeScale;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tstopWarping: function() {\n\n\t\t\tvar timeScaleInterpolant = this._timeScaleInterpolant;\n\n\t\t\tif ( timeScaleInterpolant !== null ) {\n\n\t\t\t\tthis._timeScaleInterpolant = null;\n\t\t\t\tthis._mixer._takeBackControlInterpolant( timeScaleInterpolant );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// Object Accessors\n\n\t\tgetMixer: function() {\n\n\t\t\treturn this._mixer;\n\n\t\t},\n\n\t\tgetClip: function() {\n\n\t\t\treturn this._clip;\n\n\t\t},\n\n\t\tgetRoot: function() {\n\n\t\t\treturn this._localRoot || this._mixer._root;\n\n\t\t},\n\n\t\t// Interna\n\n\t\t_update: function( time, deltaTime, timeDirection, accuIndex ) {\n\t\t\t// called by the mixer\n\n\t\t\tvar startTime = this._startTime;\n\n\t\t\tif ( startTime !== null ) {\n\n\t\t\t\t// check for scheduled start of action\n\n\t\t\t\tvar timeRunning = ( time - startTime ) * timeDirection;\n\t\t\t\tif ( timeRunning < 0 || timeDirection === 0 ) {\n\n\t\t\t\t\treturn; // yet to come / don't decide when delta = 0\n\n\t\t\t\t}\n\n\t\t\t\t// start\n\n\t\t\t\tthis._startTime = null; // unschedule\n\t\t\t\tdeltaTime = timeDirection * timeRunning;\n\n\t\t\t}\n\n\t\t\t// apply time scale and advance time\n\n\t\t\tdeltaTime *= this._updateTimeScale( time );\n\t\t\tvar clipTime = this._updateTime( deltaTime );\n\n\t\t\t// note: _updateTime may disable the action resulting in\n\t\t\t// an effective weight of 0\n\n\t\t\tvar weight = this._updateWeight( time );\n\n\t\t\tif ( weight > 0 ) {\n\n\t\t\t\tvar interpolants = this._interpolants;\n\t\t\t\tvar propertyMixers = this._propertyBindings;\n\n\t\t\t\tfor ( var j = 0, m = interpolants.length; j !== m; ++ j ) {\n\n\t\t\t\t\tinterpolants[ j ].evaluate( clipTime );\n\t\t\t\t\tpropertyMixers[ j ].accumulate( accuIndex, weight );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_updateWeight: function( time ) {\n\n\t\t\tvar weight = 0;\n\n\t\t\tif ( this.enabled ) {\n\n\t\t\t\tweight = this.weight;\n\t\t\t\tvar interpolant = this._weightInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\tweight *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopFading();\n\n\t\t\t\t\t\tif ( interpolantValue === 0 ) {\n\n\t\t\t\t\t\t\t// faded out, disable\n\t\t\t\t\t\t\tthis.enabled = false;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveWeight = weight;\n\t\t\treturn weight;\n\n\t\t},\n\n\t\t_updateTimeScale: function( time ) {\n\n\t\t\tvar timeScale = 0;\n\n\t\t\tif ( ! this.paused ) {\n\n\t\t\t\ttimeScale = this.timeScale;\n\n\t\t\t\tvar interpolant = this._timeScaleInterpolant;\n\n\t\t\t\tif ( interpolant !== null ) {\n\n\t\t\t\t\tvar interpolantValue = interpolant.evaluate( time )[ 0 ];\n\n\t\t\t\t\ttimeScale *= interpolantValue;\n\n\t\t\t\t\tif ( time > interpolant.parameterPositions[ 1 ] ) {\n\n\t\t\t\t\t\tthis.stopWarping();\n\n\t\t\t\t\t\tif ( timeScale === 0 ) {\n\n\t\t\t\t\t\t\t// motion has halted, pause\n\t\t\t\t\t\t\tthis.paused = true;\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// warp done - apply final time scale\n\t\t\t\t\t\t\tthis.timeScale = timeScale;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis._effectiveTimeScale = timeScale;\n\t\t\treturn timeScale;\n\n\t\t},\n\n\t\t_updateTime: function( deltaTime ) {\n\n\t\t\tvar time = this.time + deltaTime;\n\n\t\t\tif ( deltaTime === 0 ) return time;\n\n\t\t\tvar duration = this._clip.duration,\n\n\t\t\t\tloop = this.loop,\n\t\t\t\tloopCount = this._loopCount;\n\n\t\t\tif ( loop === LoopOnce ) {\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tthis._loopCount = 0;\n\t\t\t\t\tthis._setEndings( true, true, false );\n\n\t\t\t\t}\n\n\t\t\t\thandle_stop: {\n\n\t\t\t\t\tif ( time >= duration ) {\n\n\t\t\t\t\t\ttime = duration;\n\n\t\t\t\t\t} else if ( time < 0 ) {\n\n\t\t\t\t\t\ttime = 0;\n\n\t\t\t\t\t} else break handle_stop;\n\n\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\tdirection: deltaTime < 0 ? -1 : 1\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} else { // repetitive Repeat or PingPong\n\n\t\t\t\tvar pingPong = ( loop === LoopPingPong );\n\n\t\t\t\tif ( loopCount === -1 ) {\n\t\t\t\t\t// just started\n\n\t\t\t\t\tif ( deltaTime >= 0 ) {\n\n\t\t\t\t\t\tloopCount = 0;\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\ttrue, this.repetitions === 0, pingPong );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// when looping in reverse direction, the initial\n\t\t\t\t\t\t// transition through zero counts as a repetition,\n\t\t\t\t\t\t// so leave loopCount at -1\n\n\t\t\t\t\t\tthis._setEndings(\n\t\t\t\t\t\t\t\tthis.repetitions === 0, true, pingPong );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( time >= duration || time < 0 ) {\n\t\t\t\t\t// wrap around\n\n\t\t\t\t\tvar loopDelta = Math.floor( time / duration ); // signed\n\t\t\t\t\ttime -= duration * loopDelta;\n\n\t\t\t\t\tloopCount += Math.abs( loopDelta );\n\n\t\t\t\t\tvar pending = this.repetitions - loopCount;\n\n\t\t\t\t\tif ( pending < 0 ) {\n\t\t\t\t\t\t// have to stop (switch state, clamp time, fire event)\n\n\t\t\t\t\t\tif ( this.clampWhenFinished ) this.paused = true;\n\t\t\t\t\t\telse this.enabled = false;\n\n\t\t\t\t\t\ttime = deltaTime > 0 ? duration : 0;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'finished', action: this,\n\t\t\t\t\t\t\tdirection: deltaTime > 0 ? 1 : -1\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// keep running\n\n\t\t\t\t\t\tif ( pending === 0 ) {\n\t\t\t\t\t\t\t// entering the last round\n\n\t\t\t\t\t\t\tvar atStart = deltaTime < 0;\n\t\t\t\t\t\t\tthis._setEndings( atStart, ! atStart, pingPong );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tthis._setEndings( false, false, pingPong );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._loopCount = loopCount;\n\n\t\t\t\t\t\tthis._mixer.dispatchEvent( {\n\t\t\t\t\t\t\ttype: 'loop', action: this, loopDelta: loopDelta\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( pingPong && ( loopCount & 1 ) === 1 ) {\n\t\t\t\t\t// invert time for the \"pong round\"\n\n\t\t\t\t\tthis.time = time;\n\t\t\t\t\treturn duration - time;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.time = time;\n\t\t\treturn time;\n\n\t\t},\n\n\t\t_setEndings: function( atStart, atEnd, pingPong ) {\n\n\t\t\tvar settings = this._interpolantSettings;\n\n\t\t\tif ( pingPong ) {\n\n\t\t\t\tsettings.endingStart \t= ZeroSlopeEnding;\n\t\t\t\tsettings.endingEnd\t\t= ZeroSlopeEnding;\n\n\t\t\t} else {\n\n\t\t\t\t// assuming for LoopOnce atStart == atEnd == true\n\n\t\t\t\tif ( atStart ) {\n\n\t\t\t\t\tsettings.endingStart = this.zeroSlopeAtStart ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingStart = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t\tif ( atEnd ) {\n\n\t\t\t\t\tsettings.endingEnd = this.zeroSlopeAtEnd ?\n\t\t\t\t\t\t\tZeroSlopeEnding : ZeroCurvatureEnding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsettings.endingEnd \t = WrapAroundEnding;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_scheduleFading: function( duration, weightNow, weightThen ) {\n\n\t\t\tvar mixer = this._mixer, now = mixer.time,\n\t\t\t\tinterpolant = this._weightInterpolant;\n\n\t\t\tif ( interpolant === null ) {\n\n\t\t\t\tinterpolant = mixer._lendControlInterpolant();\n\t\t\t\tthis._weightInterpolant = interpolant;\n\n\t\t\t}\n\n\t\t\tvar times = interpolant.parameterPositions,\n\t\t\t\tvalues = interpolant.sampleValues;\n\n\t\t\ttimes[ 0 ] = now; \t\t\t\tvalues[ 0 ] = weightNow;\n\t\t\ttimes[ 1 ] = now + duration;\tvalues[ 1 ] = weightThen;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t *\n\t * Player for AnimationClips.\n\t *\n\t *\n\t * @author Ben Houston / http://clara.io/\n\t * @author David Sarno / http://lighthaus.us/\n\t * @author tschw\n\t */\n\n\tfunction AnimationMixer( root ) {\n\n\t\tthis._root = root;\n\t\tthis._initMemoryManager();\n\t\tthis._accuIndex = 0;\n\n\t\tthis.time = 0;\n\n\t\tthis.timeScale = 1.0;\n\n\t}\n\n\tAnimationMixer.prototype = {\n\n\t\tconstructor: AnimationMixer,\n\n\t\t// return an action for a clip optionally using a custom root target\n\t\t// object (this method allocates a lot of dynamic memory in case a\n\t\t// previously unknown clip/root combination is specified)\n\t\tclipAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject !== null ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ],\n\t\t\t\tprototypeAction = null;\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\tvar existingAction =\n\t\t\t\t\t\tactionsForClip.actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( existingAction !== undefined ) {\n\n\t\t\t\t\treturn existingAction;\n\n\t\t\t\t}\n\n\t\t\t\t// we know the clip, so we don't have to parse all\n\t\t\t\t// the bindings again but can just copy\n\t\t\t\tprototypeAction = actionsForClip.knownActions[ 0 ];\n\n\t\t\t\t// also, take the clip from the prototype action\n\t\t\t\tif ( clipObject === null )\n\t\t\t\t\tclipObject = prototypeAction._clip;\n\n\t\t\t}\n\n\t\t\t// clip must be known when specified via string\n\t\t\tif ( clipObject === null ) return null;\n\n\t\t\t// allocate all resources required to run it\n\t\t\tvar newAction = new AnimationAction( this, clipObject, optionalRoot );\n\n\t\t\tthis._bindAction( newAction, prototypeAction );\n\n\t\t\t// and make the action known to the memory manager\n\t\t\tthis._addInactiveAction( newAction, clipUuid, rootUuid );\n\n\t\t\treturn newAction;\n\n\t\t},\n\n\t\t// get an existing action\n\t\texistingAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar root = optionalRoot || this._root,\n\t\t\t\trootUuid = root.uuid,\n\n\t\t\t\tclipObject = typeof clip === 'string' ?\n\t\t\t\t\t\tAnimationClip.findByName( root, clip ) : clip,\n\n\t\t\t\tclipUuid = clipObject ? clipObject.uuid : clip,\n\n\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\treturn actionsForClip.actionByRoot[ rootUuid ] || null;\n\n\t\t\t}\n\n\t\t\treturn null;\n\n\t\t},\n\n\t\t// deactivates all previously scheduled actions\n\t\tstopAllAction: function () {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\t\t\t\tbindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tthis._nActiveActions = 0;\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tactions[ i ].reset();\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].useCount = 0;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// advance the time and update apply the animation\n\t\tupdate: function ( deltaTime ) {\n\n\t\t\tdeltaTime *= this.timeScale;\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tnActions = this._nActiveActions,\n\n\t\t\t\ttime = this.time += deltaTime,\n\t\t\t\ttimeDirection = Math.sign( deltaTime ),\n\n\t\t\t\taccuIndex = this._accuIndex ^= 1;\n\n\t\t\t// run active actions\n\n\t\t\tfor ( var i = 0; i !== nActions; ++ i ) {\n\n\t\t\t\tvar action = actions[ i ];\n\n\t\t\t\tif ( action.enabled ) {\n\n\t\t\t\t\taction._update( time, deltaTime, timeDirection, accuIndex );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// update scene graph\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tnBindings = this._nActiveBindings;\n\n\t\t\tfor ( var i = 0; i !== nBindings; ++ i ) {\n\n\t\t\t\tbindings[ i ].apply( accuIndex );\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// return this mixer's root target object\n\t\tgetRoot: function () {\n\n\t\t\treturn this._root;\n\n\t\t},\n\n\t\t// free all resources specific to a particular clip\n\t\tuncacheClip: function ( clip ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tclipUuid = clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip !== undefined ) {\n\n\t\t\t\t// note: just calling _removeInactiveAction would mess up the\n\t\t\t\t// iteration state and also require updating the state we can\n\t\t\t\t// just throw away\n\n\t\t\t\tvar actionsToRemove = actionsForClip.knownActions;\n\n\t\t\t\tfor ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar action = actionsToRemove[ i ];\n\n\t\t\t\t\tthis._deactivateAction( action );\n\n\t\t\t\t\tvar cacheIndex = action._cacheIndex,\n\t\t\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ];\n\n\t\t\t\t\taction._cacheIndex = null;\n\t\t\t\t\taction._byClipCacheIndex = null;\n\n\t\t\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\t\t\tactions.pop();\n\n\t\t\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t\t\t}\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t// free all resources specific to a particular root target object\n\t\tuncacheRoot: function ( root ) {\n\n\t\t\tvar rootUuid = root.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip;\n\n\t\t\tfor ( var clipUuid in actionsByClip ) {\n\n\t\t\t\tvar actionByRoot = actionsByClip[ clipUuid ].actionByRoot,\n\t\t\t\t\taction = actionByRoot[ rootUuid ];\n\n\t\t\t\tif ( action !== undefined ) {\n\n\t\t\t\t\tthis._deactivateAction( action );\n\t\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingByName !== undefined ) {\n\n\t\t\t\tfor ( var trackName in bindingByName ) {\n\n\t\t\t\t\tvar binding = bindingByName[ trackName ];\n\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t// remove a targeted clip from the cache\n\t\tuncacheAction: function ( clip, optionalRoot ) {\n\n\t\t\tvar action = this.existingAction( clip, optionalRoot );\n\n\t\t\tif ( action !== null ) {\n\n\t\t\t\tthis._deactivateAction( action );\n\t\t\t\tthis._removeInactiveAction( action );\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t// Implementation details:\n\n\tObject.assign( AnimationMixer.prototype, {\n\n\t\t_bindAction: function ( action, prototypeAction ) {\n\n\t\t\tvar root = action._localRoot || this._root,\n\t\t\t\ttracks = action._clip.tracks,\n\t\t\t\tnTracks = tracks.length,\n\t\t\t\tbindings = action._propertyBindings,\n\t\t\t\tinterpolants = action._interpolants,\n\t\t\t\trootUuid = root.uuid,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingsByName = bindingsByRoot[ rootUuid ];\n\n\t\t\tif ( bindingsByName === undefined ) {\n\n\t\t\t\tbindingsByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingsByName;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i !== nTracks; ++ i ) {\n\n\t\t\t\tvar track = tracks[ i ],\n\t\t\t\t\ttrackName = track.name,\n\t\t\t\t\tbinding = bindingsByName[ trackName ];\n\n\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbinding = bindings[ i ];\n\n\t\t\t\t\tif ( binding !== undefined ) {\n\n\t\t\t\t\t\t// existing binding, make sure the cache knows\n\n\t\t\t\t\t\tif ( binding._cacheIndex === null ) {\n\n\t\t\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tvar path = prototypeAction && prototypeAction.\n\t\t\t\t\t\t\t_propertyBindings[ i ].binding.parsedPath;\n\n\t\t\t\t\tbinding = new PropertyMixer(\n\t\t\t\t\t\t\tPropertyBinding.create( root, trackName, path ),\n\t\t\t\t\t\t\ttrack.ValueTypeName, track.getValueSize() );\n\n\t\t\t\t\t++ binding.referenceCount;\n\t\t\t\t\tthis._addInactiveBinding( binding, rootUuid, trackName );\n\n\t\t\t\t\tbindings[ i ] = binding;\n\n\t\t\t\t}\n\n\t\t\t\tinterpolants[ i ].resultBuffer = binding.buffer;\n\n\t\t\t}\n\n\t\t},\n\n\t\t_activateAction: function ( action ) {\n\n\t\t\tif ( ! this._isActiveAction( action ) ) {\n\n\t\t\t\tif ( action._cacheIndex === null ) {\n\n\t\t\t\t\t// this action has been forgotten by the cache, but the user\n\t\t\t\t\t// appears to be still using it -> rebind\n\n\t\t\t\t\tvar rootUuid = ( action._localRoot || this._root ).uuid,\n\t\t\t\t\t\tclipUuid = action._clip.uuid,\n\t\t\t\t\t\tactionsForClip = this._actionsByClip[ clipUuid ];\n\n\t\t\t\t\tthis._bindAction( action,\n\t\t\t\t\t\t\tactionsForClip && actionsForClip.knownActions[ 0 ] );\n\n\t\t\t\t\tthis._addInactiveAction( action, clipUuid, rootUuid );\n\n\t\t\t\t}\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// increment reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( binding.useCount ++ === 0 ) {\n\n\t\t\t\t\t\tthis._lendBinding( binding );\n\t\t\t\t\t\tbinding.saveOriginalState();\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._lendAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t_deactivateAction: function ( action ) {\n\n\t\t\tif ( this._isActiveAction( action ) ) {\n\n\t\t\t\tvar bindings = action._propertyBindings;\n\n\t\t\t\t// decrement reference counts / sort out state\n\t\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\t\tif ( -- binding.useCount === 0 ) {\n\n\t\t\t\t\t\tbinding.restoreOriginalState();\n\t\t\t\t\t\tthis._takeBackBinding( binding );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._takeBackAction( action );\n\n\t\t\t}\n\n\t\t},\n\n\t\t// Memory manager\n\n\t\t_initMemoryManager: function () {\n\n\t\t\tthis._actions = []; // 'nActiveActions' followed by inactive ones\n\t\t\tthis._nActiveActions = 0;\n\n\t\t\tthis._actionsByClip = {};\n\t\t\t// inside:\n\t\t\t// {\n\t\t\t// \t\tknownActions: Array< AnimationAction >\t- used as prototypes\n\t\t\t// \t\tactionByRoot: AnimationAction\t\t\t- lookup\n\t\t\t// }\n\n\n\t\t\tthis._bindings = []; // 'nActiveBindings' followed by inactive ones\n\t\t\tthis._nActiveBindings = 0;\n\n\t\t\tthis._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >\n\n\n\t\t\tthis._controlInterpolants = []; // same game as above\n\t\t\tthis._nActiveControlInterpolants = 0;\n\n\t\t\tvar scope = this;\n\n\t\t\tthis.stats = {\n\n\t\t\t\tactions: {\n\t\t\t\t\tget total() { return scope._actions.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveActions; }\n\t\t\t\t},\n\t\t\t\tbindings: {\n\t\t\t\t\tget total() { return scope._bindings.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveBindings; }\n\t\t\t\t},\n\t\t\t\tcontrolInterpolants: {\n\t\t\t\t\tget total() { return scope._controlInterpolants.length; },\n\t\t\t\t\tget inUse() { return scope._nActiveControlInterpolants; }\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t},\n\n\t\t// Memory management for AnimationAction objects\n\n\t\t_isActiveAction: function ( action ) {\n\n\t\t\tvar index = action._cacheIndex;\n\t\t\treturn index !== null && index < this._nActiveActions;\n\n\t\t},\n\n\t\t_addInactiveAction: function ( action, clipUuid, rootUuid ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ];\n\n\t\t\tif ( actionsForClip === undefined ) {\n\n\t\t\t\tactionsForClip = {\n\n\t\t\t\t\tknownActions: [ action ],\n\t\t\t\t\tactionByRoot: {}\n\n\t\t\t\t};\n\n\t\t\t\taction._byClipCacheIndex = 0;\n\n\t\t\t\tactionsByClip[ clipUuid ] = actionsForClip;\n\n\t\t\t} else {\n\n\t\t\t\tvar knownActions = actionsForClip.knownActions;\n\n\t\t\t\taction._byClipCacheIndex = knownActions.length;\n\t\t\t\tknownActions.push( action );\n\n\t\t\t}\n\n\t\t\taction._cacheIndex = actions.length;\n\t\t\tactions.push( action );\n\n\t\t\tactionsForClip.actionByRoot[ rootUuid ] = action;\n\n\t\t},\n\n\t\t_removeInactiveAction: function ( action ) {\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tlastInactiveAction = actions[ actions.length - 1 ],\n\t\t\t\tcacheIndex = action._cacheIndex;\n\n\t\t\tlastInactiveAction._cacheIndex = cacheIndex;\n\t\t\tactions[ cacheIndex ] = lastInactiveAction;\n\t\t\tactions.pop();\n\n\t\t\taction._cacheIndex = null;\n\n\n\t\t\tvar clipUuid = action._clip.uuid,\n\t\t\t\tactionsByClip = this._actionsByClip,\n\t\t\t\tactionsForClip = actionsByClip[ clipUuid ],\n\t\t\t\tknownActionsForClip = actionsForClip.knownActions,\n\n\t\t\t\tlastKnownAction =\n\t\t\t\t\tknownActionsForClip[ knownActionsForClip.length - 1 ],\n\n\t\t\t\tbyClipCacheIndex = action._byClipCacheIndex;\n\n\t\t\tlastKnownAction._byClipCacheIndex = byClipCacheIndex;\n\t\t\tknownActionsForClip[ byClipCacheIndex ] = lastKnownAction;\n\t\t\tknownActionsForClip.pop();\n\n\t\t\taction._byClipCacheIndex = null;\n\n\n\t\t\tvar actionByRoot = actionsForClip.actionByRoot,\n\t\t\t\trootUuid = ( actions._localRoot || this._root ).uuid;\n\n\t\t\tdelete actionByRoot[ rootUuid ];\n\n\t\t\tif ( knownActionsForClip.length === 0 ) {\n\n\t\t\t\tdelete actionsByClip[ clipUuid ];\n\n\t\t\t}\n\n\t\t\tthis._removeInactiveBindingsForAction( action );\n\n\t\t},\n\n\t\t_removeInactiveBindingsForAction: function ( action ) {\n\n\t\t\tvar bindings = action._propertyBindings;\n\t\t\tfor ( var i = 0, n = bindings.length; i !== n; ++ i ) {\n\n\t\t\t\tvar binding = bindings[ i ];\n\n\t\t\t\tif ( -- binding.referenceCount === 0 ) {\n\n\t\t\t\t\tthis._removeInactiveBinding( binding );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions >| inactive actions ]\n\t\t\t// s a\n\t\t\t// <-swap->\n\t\t\t// a s\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveActions ++,\n\n\t\t\t\tfirstInactiveAction = actions[ lastActiveIndex ];\n\n\t\t\taction._cacheIndex = lastActiveIndex;\n\t\t\tactions[ lastActiveIndex ] = action;\n\n\t\t\tfirstInactiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = firstInactiveAction;\n\n\t\t},\n\n\t\t_takeBackAction: function ( action ) {\n\n\t\t\t// [ active actions | inactive actions ]\n\t\t\t// [ active actions |< inactive actions ]\n\t\t\t// a s\n\t\t\t// <-swap->\n\t\t\t// s a\n\n\t\t\tvar actions = this._actions,\n\t\t\t\tprevIndex = action._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveActions,\n\n\t\t\t\tlastActiveAction = actions[ firstInactiveIndex ];\n\n\t\t\taction._cacheIndex = firstInactiveIndex;\n\t\t\tactions[ firstInactiveIndex ] = action;\n\n\t\t\tlastActiveAction._cacheIndex = prevIndex;\n\t\t\tactions[ prevIndex ] = lastActiveAction;\n\n\t\t},\n\n\t\t// Memory management for PropertyMixer objects\n\n\t\t_addInactiveBinding: function ( binding, rootUuid, trackName ) {\n\n\t\t\tvar bindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tbindings = this._bindings;\n\n\t\t\tif ( bindingByName === undefined ) {\n\n\t\t\t\tbindingByName = {};\n\t\t\t\tbindingsByRoot[ rootUuid ] = bindingByName;\n\n\t\t\t}\n\n\t\t\tbindingByName[ trackName ] = binding;\n\n\t\t\tbinding._cacheIndex = bindings.length;\n\t\t\tbindings.push( binding );\n\n\t\t},\n\n\t\t_removeInactiveBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tpropBinding = binding.binding,\n\t\t\t\trootUuid = propBinding.rootNode.uuid,\n\t\t\t\ttrackName = propBinding.path,\n\t\t\t\tbindingsByRoot = this._bindingsByRootAndName,\n\t\t\t\tbindingByName = bindingsByRoot[ rootUuid ],\n\n\t\t\t\tlastInactiveBinding = bindings[ bindings.length - 1 ],\n\t\t\t\tcacheIndex = binding._cacheIndex;\n\n\t\t\tlastInactiveBinding._cacheIndex = cacheIndex;\n\t\t\tbindings[ cacheIndex ] = lastInactiveBinding;\n\t\t\tbindings.pop();\n\n\t\t\tdelete bindingByName[ trackName ];\n\n\t\t\tremove_empty_map: {\n\n\t\t\t\tfor ( var _ in bindingByName ) break remove_empty_map;\n\n\t\t\t\tdelete bindingsByRoot[ rootUuid ];\n\n\t\t\t}\n\n\t\t},\n\n\t\t_lendBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tlastActiveIndex = this._nActiveBindings ++,\n\n\t\t\t\tfirstInactiveBinding = bindings[ lastActiveIndex ];\n\n\t\t\tbinding._cacheIndex = lastActiveIndex;\n\t\t\tbindings[ lastActiveIndex ] = binding;\n\n\t\t\tfirstInactiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = firstInactiveBinding;\n\n\t\t},\n\n\t\t_takeBackBinding: function ( binding ) {\n\n\t\t\tvar bindings = this._bindings,\n\t\t\t\tprevIndex = binding._cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveBindings,\n\n\t\t\t\tlastActiveBinding = bindings[ firstInactiveIndex ];\n\n\t\t\tbinding._cacheIndex = firstInactiveIndex;\n\t\t\tbindings[ firstInactiveIndex ] = binding;\n\n\t\t\tlastActiveBinding._cacheIndex = prevIndex;\n\t\t\tbindings[ prevIndex ] = lastActiveBinding;\n\n\t\t},\n\n\n\t\t// Memory management of Interpolants for weight and time scale\n\n\t\t_lendControlInterpolant: function () {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tlastActiveIndex = this._nActiveControlInterpolants ++,\n\t\t\t\tinterpolant = interpolants[ lastActiveIndex ];\n\n\t\t\tif ( interpolant === undefined ) {\n\n\t\t\t\tinterpolant = new LinearInterpolant(\n\t\t\t\t\t\tnew Float32Array( 2 ), new Float32Array( 2 ),\n\t\t\t\t\t\t\t1, this._controlInterpolantsResultBuffer );\n\n\t\t\t\tinterpolant.__cacheIndex = lastActiveIndex;\n\t\t\t\tinterpolants[ lastActiveIndex ] = interpolant;\n\n\t\t\t}\n\n\t\t\treturn interpolant;\n\n\t\t},\n\n\t\t_takeBackControlInterpolant: function ( interpolant ) {\n\n\t\t\tvar interpolants = this._controlInterpolants,\n\t\t\t\tprevIndex = interpolant.__cacheIndex,\n\n\t\t\t\tfirstInactiveIndex = -- this._nActiveControlInterpolants,\n\n\t\t\t\tlastActiveInterpolant = interpolants[ firstInactiveIndex ];\n\n\t\t\tinterpolant.__cacheIndex = firstInactiveIndex;\n\t\t\tinterpolants[ firstInactiveIndex ] = interpolant;\n\n\t\t\tlastActiveInterpolant.__cacheIndex = prevIndex;\n\t\t\tinterpolants[ prevIndex ] = lastActiveInterpolant;\n\n\t\t},\n\n\t\t_controlInterpolantsResultBuffer: new Float32Array( 1 )\n\n\t} );\n\n\tObject.assign( AnimationMixer.prototype, EventDispatcher.prototype );\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Uniform( value ) {\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tconsole.warn( 'THREE.Uniform: Type parameter is no longer needed.' );\n\t\t\tvalue = arguments[ 1 ];\n\n\t\t}\n\n\t\tthis.value = value;\n\n\t}\n\n\tUniform.prototype.clone = function () {\n\n\t\treturn new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferGeometry() {\n\n\t\tBufferGeometry.call( this );\n\n\t\tthis.type = 'InstancedBufferGeometry';\n\t\tthis.maxInstancedCount = undefined;\n\n\t}\n\n\tInstancedBufferGeometry.prototype = Object.create( BufferGeometry.prototype );\n\tInstancedBufferGeometry.prototype.constructor = InstancedBufferGeometry;\n\n\tInstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;\n\n\tInstancedBufferGeometry.prototype.addGroup = function ( start, count, materialIndex ) {\n\n\t\tthis.groups.push( {\n\n\t\t\tstart: start,\n\t\t\tcount: count,\n\t\t\tmaterialIndex: materialIndex\n\n\t\t} );\n\n\t};\n\n\tInstancedBufferGeometry.prototype.copy = function ( source ) {\n\n\t\tvar index = source.index;\n\n\t\tif ( index !== null ) {\n\n\t\t\tthis.setIndex( index.clone() );\n\n\t\t}\n\n\t\tvar attributes = source.attributes;\n\n\t\tfor ( var name in attributes ) {\n\n\t\t\tvar attribute = attributes[ name ];\n\t\t\tthis.addAttribute( name, attribute.clone() );\n\n\t\t}\n\n\t\tvar groups = source.groups;\n\n\t\tfor ( var i = 0, l = groups.length; i < l; i ++ ) {\n\n\t\t\tvar group = groups[ i ];\n\t\t\tthis.addGroup( group.start, group.count, group.materialIndex );\n\n\t\t}\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.data = interleavedBuffer;\n\t\tthis.itemSize = itemSize;\n\t\tthis.offset = offset;\n\n\t\tthis.normalized = normalized === true;\n\n\t}\n\n\n\tInterleavedBufferAttribute.prototype = {\n\n\t\tconstructor: InterleavedBufferAttribute,\n\n\t\tisInterleavedBufferAttribute: true,\n\n\t\tget count() {\n\n\t\t\treturn this.data.count;\n\n\t\t},\n\n\t\tget array() {\n\n\t\t\treturn this.data.array;\n\n\t\t},\n\n\t\tsetX: function ( index, x ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset ] = x;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetY: function ( index, y ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetZ: function ( index, z ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetW: function ( index, w ) {\n\n\t\t\tthis.data.array[ index * this.data.stride + this.offset + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tgetX: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset ];\n\n\t\t},\n\n\t\tgetY: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 1 ];\n\n\t\t},\n\n\t\tgetZ: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 2 ];\n\n\t\t},\n\n\t\tgetW: function ( index ) {\n\n\t\t\treturn this.data.array[ index * this.data.stride + this.offset + 3 ];\n\n\t\t},\n\n\t\tsetXY: function ( index, x, y ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZ: function ( index, x, y, z ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetXYZW: function ( index, x, y, z, w ) {\n\n\t\t\tindex = index * this.data.stride + this.offset;\n\n\t\t\tthis.data.array[ index + 0 ] = x;\n\t\t\tthis.data.array[ index + 1 ] = y;\n\t\t\tthis.data.array[ index + 2 ] = z;\n\t\t\tthis.data.array[ index + 3 ] = w;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InterleavedBuffer( array, stride ) {\n\n\t\tthis.uuid = _Math.generateUUID();\n\n\t\tthis.array = array;\n\t\tthis.stride = stride;\n\t\tthis.count = array !== undefined ? array.length / stride : 0;\n\n\t\tthis.dynamic = false;\n\t\tthis.updateRange = { offset: 0, count: - 1 };\n\n\t\tthis.onUploadCallback = function () {};\n\n\t\tthis.version = 0;\n\n\t}\n\n\tInterleavedBuffer.prototype = {\n\n\t\tconstructor: InterleavedBuffer,\n\n\t\tisInterleavedBuffer: true,\n\n\t\tset needsUpdate( value ) {\n\n\t\t\tif ( value === true ) this.version ++;\n\n\t\t},\n\n\t\tsetArray: function ( array ) {\n\n\t\t\tif ( Array.isArray( array ) ) {\n\n\t\t\t\tthrow new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );\n\n\t\t\t}\n\n\t\t\tthis.count = array !== undefined ? array.length / this.stride : 0;\n\t\t\tthis.array = array;\n\n\t\t},\n\n\t\tsetDynamic: function ( value ) {\n\n\t\t\tthis.dynamic = value;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopy: function ( source ) {\n\n\t\t\tthis.array = new source.array.constructor( source.array );\n\t\t\tthis.count = source.count;\n\t\t\tthis.stride = source.stride;\n\t\t\tthis.dynamic = source.dynamic;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tcopyAt: function ( index1, attribute, index2 ) {\n\n\t\t\tindex1 *= this.stride;\n\t\t\tindex2 *= attribute.stride;\n\n\t\t\tfor ( var i = 0, l = this.stride; i < l; i ++ ) {\n\n\t\t\t\tthis.array[ index1 + i ] = attribute.array[ index2 + i ];\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tset: function ( value, offset ) {\n\n\t\t\tif ( offset === undefined ) offset = 0;\n\n\t\t\tthis.array.set( value, offset );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tonUpload: function ( callback ) {\n\n\t\t\tthis.onUploadCallback = callback;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {\n\n\t\tInterleavedBuffer.call( this, array, stride );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedInterleavedBuffer.prototype = Object.create( InterleavedBuffer.prototype );\n\tInstancedInterleavedBuffer.prototype.constructor = InstancedInterleavedBuffer;\n\n\tInstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;\n\n\tInstancedInterleavedBuffer.prototype.copy = function ( source ) {\n\n\t\tInterleavedBuffer.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author benaadams / https://twitter.com/ben_a_adams\n\t */\n\n\tfunction InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {\n\n\t\tBufferAttribute.call( this, array, itemSize );\n\n\t\tthis.meshPerAttribute = meshPerAttribute || 1;\n\n\t}\n\n\tInstancedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );\n\tInstancedBufferAttribute.prototype.constructor = InstancedBufferAttribute;\n\n\tInstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;\n\n\tInstancedBufferAttribute.prototype.copy = function ( source ) {\n\n\t\tBufferAttribute.prototype.copy.call( this, source );\n\n\t\tthis.meshPerAttribute = source.meshPerAttribute;\n\n\t\treturn this;\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author bhouston / http://clara.io/\n\t * @author stephomi / http://stephaneginier.com/\n\t */\n\n\tfunction Raycaster( origin, direction, near, far ) {\n\n\t\tthis.ray = new Ray( origin, direction );\n\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\tthis.near = near || 0;\n\t\tthis.far = far || Infinity;\n\n\t\tthis.params = {\n\t\t\tMesh: {},\n\t\t\tLine: {},\n\t\t\tLOD: {},\n\t\t\tPoints: { threshold: 1 },\n\t\t\tSprite: {}\n\t\t};\n\n\t\tObject.defineProperties( this.params, {\n\t\t\tPointCloud: {\n\t\t\t\tget: function () {\n\t\t\t\t\tconsole.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );\n\t\t\t\t\treturn this.Points;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t}\n\n\tfunction ascSort( a, b ) {\n\n\t\treturn a.distance - b.distance;\n\n\t}\n\n\tfunction intersectObject( object, raycaster, intersects, recursive ) {\n\n\t\tif ( object.visible === false ) return;\n\n\t\tobject.raycast( raycaster, intersects );\n\n\t\tif ( recursive === true ) {\n\n\t\t\tvar children = object.children;\n\n\t\t\tfor ( var i = 0, l = children.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( children[ i ], raycaster, intersects, true );\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\t//\n\n\tRaycaster.prototype = {\n\n\t\tconstructor: Raycaster,\n\n\t\tlinePrecision: 1,\n\n\t\tset: function ( origin, direction ) {\n\n\t\t\t// direction is assumed to be normalized (for accurate distance calculations)\n\n\t\t\tthis.ray.set( origin, direction );\n\n\t\t},\n\n\t\tsetFromCamera: function ( coords, camera ) {\n\n\t\t\tif ( (camera && camera.isPerspectiveCamera) ) {\n\n\t\t\t\tthis.ray.origin.setFromMatrixPosition( camera.matrixWorld );\n\t\t\t\tthis.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();\n\n\t\t\t} else if ( (camera && camera.isOrthographicCamera) ) {\n\n\t\t\t\tthis.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera\n\t\t\t\tthis.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );\n\n\t\t\t} else {\n\n\t\t\t\tconsole.error( 'THREE.Raycaster: Unsupported camera type.' );\n\n\t\t\t}\n\n\t\t},\n\n\t\tintersectObject: function ( object, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tintersectObject( object, this, intersects, recursive );\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t},\n\n\t\tintersectObjects: function ( objects, recursive ) {\n\n\t\t\tvar intersects = [];\n\n\t\t\tif ( Array.isArray( objects ) === false ) {\n\n\t\t\t\tconsole.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );\n\t\t\t\treturn intersects;\n\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = objects.length; i < l; i ++ ) {\n\n\t\t\t\tintersectObject( objects[ i ], this, intersects, recursive );\n\n\t\t\t}\n\n\t\t\tintersects.sort( ascSort );\n\n\t\t\treturn intersects;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction Clock( autoStart ) {\n\n\t\tthis.autoStart = ( autoStart !== undefined ) ? autoStart : true;\n\n\t\tthis.startTime = 0;\n\t\tthis.oldTime = 0;\n\t\tthis.elapsedTime = 0;\n\n\t\tthis.running = false;\n\n\t}\n\n\tClock.prototype = {\n\n\t\tconstructor: Clock,\n\n\t\tstart: function () {\n\n\t\t\tthis.startTime = ( performance || Date ).now();\n\n\t\t\tthis.oldTime = this.startTime;\n\t\t\tthis.elapsedTime = 0;\n\t\t\tthis.running = true;\n\n\t\t},\n\n\t\tstop: function () {\n\n\t\t\tthis.getElapsedTime();\n\t\t\tthis.running = false;\n\n\t\t},\n\n\t\tgetElapsedTime: function () {\n\n\t\t\tthis.getDelta();\n\t\t\treturn this.elapsedTime;\n\n\t\t},\n\n\t\tgetDelta: function () {\n\n\t\t\tvar diff = 0;\n\n\t\t\tif ( this.autoStart && ! this.running ) {\n\n\t\t\t\tthis.start();\n\n\t\t\t}\n\n\t\t\tif ( this.running ) {\n\n\t\t\t\tvar newTime = ( performance || Date ).now();\n\n\t\t\t\tdiff = ( newTime - this.oldTime ) / 1000;\n\t\t\t\tthis.oldTime = newTime;\n\n\t\t\t\tthis.elapsedTime += diff;\n\n\t\t\t}\n\n\t\t\treturn diff;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author bhouston / http://clara.io\n\t * @author WestLangley / http://github.com/WestLangley\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system\n\t *\n\t * The poles (phi) are at the positive and negative y axis.\n\t * The equator starts at positive z.\n\t */\n\n\tfunction Spherical( radius, phi, theta ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0;\n\t\tthis.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere\n\n\t\treturn this;\n\n\t}\n\n\tSpherical.prototype = {\n\n\t\tconstructor: Spherical,\n\n\t\tset: function ( radius, phi, theta ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.phi = phi;\n\t\t\tthis.theta = theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.phi = other.phi;\n\t\t\tthis.theta = other.theta;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tmakeSafe: function() {\n\n\t\t\tvar EPS = 0.000001;\n\t\t\tthis.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = vec3.length();\n\n\t\t\tif ( this.radius === 0 ) {\n\n\t\t\t\tthis.theta = 0;\n\t\t\t\tthis.phi = 0;\n\n\t\t\t} else {\n\n\t\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis\n\t\t\t\tthis.phi = Math.acos( _Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system\n\t *\n\t */\n\n\tfunction Cylindrical( radius, theta, y ) {\n\n\t\tthis.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane\n\t\tthis.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis\n\t\tthis.y = ( y !== undefined ) ? y : 0; // height above the x-z plane\n\n\t\treturn this;\n\n\t}\n\n\tCylindrical.prototype = {\n\n\t\tconstructor: Cylindrical,\n\n\t\tset: function ( radius, theta, y ) {\n\n\t\t\tthis.radius = radius;\n\t\t\tthis.theta = theta;\n\t\t\tthis.y = y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tclone: function () {\n\n\t\t\treturn new this.constructor().copy( this );\n\n\t\t},\n\n\t\tcopy: function ( other ) {\n\n\t\t\tthis.radius = other.radius;\n\t\t\tthis.theta = other.theta;\n\t\t\tthis.y = other.y;\n\n\t\t\treturn this;\n\n\t\t},\n\n\t\tsetFromVector3: function( vec3 ) {\n\n\t\t\tthis.radius = Math.sqrt( vec3.x * vec3.x + vec3.z * vec3.z );\n\t\t\tthis.theta = Math.atan2( vec3.x, vec3.z );\n\t\t\tthis.y = vec3.y;\n\n\t\t\treturn this;\n\n\t\t}\n\n\t};\n\n\t/**\r\n\t * @author alteredq / http://alteredqualia.com/\r\n\t */\r\n\r\n\tfunction MorphBlendMesh( geometry, material ) {\n\r\n\t\tMesh.call( this, geometry, material );\r\n\r\n\t\tthis.animationsMap = {};\r\n\t\tthis.animationsList = [];\r\n\r\n\t\t// prepare default animation\r\n\t\t// (all frames played together in 1 second)\r\n\r\n\t\tvar numFrames = this.geometry.morphTargets.length;\r\n\r\n\t\tvar name = \"__default\";\r\n\r\n\t\tvar startFrame = 0;\r\n\t\tvar endFrame = numFrames - 1;\r\n\r\n\t\tvar fps = numFrames / 1;\r\n\r\n\t\tthis.createAnimation( name, startFrame, endFrame, fps );\r\n\t\tthis.setAnimationWeight( name, 1 );\r\n\r\n\t}\r\n\r\n\tMorphBlendMesh.prototype = Object.create( Mesh.prototype );\r\n\tMorphBlendMesh.prototype.constructor = MorphBlendMesh;\r\n\r\n\tMorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {\r\n\r\n\t\tvar animation = {\r\n\r\n\t\t\tstart: start,\r\n\t\t\tend: end,\r\n\r\n\t\t\tlength: end - start + 1,\r\n\r\n\t\t\tfps: fps,\r\n\t\t\tduration: ( end - start ) / fps,\r\n\r\n\t\t\tlastFrame: 0,\r\n\t\t\tcurrentFrame: 0,\r\n\r\n\t\t\tactive: false,\r\n\r\n\t\t\ttime: 0,\r\n\t\t\tdirection: 1,\r\n\t\t\tweight: 1,\r\n\r\n\t\t\tdirectionBackwards: false,\r\n\t\t\tmirroredLoop: false\r\n\r\n\t\t};\r\n\r\n\t\tthis.animationsMap[ name ] = animation;\r\n\t\tthis.animationsList.push( animation );\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {\r\n\r\n\t\tvar pattern = /([a-z]+)_?(\\d+)/i;\r\n\r\n\t\tvar firstAnimation, frameRanges = {};\r\n\r\n\t\tvar geometry = this.geometry;\r\n\r\n\t\tfor ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar morph = geometry.morphTargets[ i ];\r\n\t\t\tvar chunks = morph.name.match( pattern );\r\n\r\n\t\t\tif ( chunks && chunks.length > 1 ) {\r\n\r\n\t\t\t\tvar name = chunks[ 1 ];\r\n\r\n\t\t\t\tif ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: - Infinity };\r\n\r\n\t\t\t\tvar range = frameRanges[ name ];\r\n\r\n\t\t\t\tif ( i < range.start ) range.start = i;\r\n\t\t\t\tif ( i > range.end ) range.end = i;\r\n\r\n\t\t\t\tif ( ! firstAnimation ) firstAnimation = name;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfor ( var name in frameRanges ) {\r\n\r\n\t\t\tvar range = frameRanges[ name ];\r\n\t\t\tthis.createAnimation( name, range.start, range.end, fps );\r\n\r\n\t\t}\r\n\r\n\t\tthis.firstAnimation = firstAnimation;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = 1;\r\n\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.direction = - 1;\r\n\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.fps = fps;\r\n\t\t\tanimation.duration = ( animation.end - animation.start ) / animation.fps;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.duration = duration;\r\n\t\t\tanimation.fps = ( animation.end - animation.start ) / animation.duration;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.weight = weight;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = time;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationTime = function ( name ) {\r\n\r\n\t\tvar time = 0;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\ttime = animation.time;\r\n\r\n\t\t}\r\n\r\n\t\treturn time;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.getAnimationDuration = function ( name ) {\r\n\r\n\t\tvar duration = - 1;\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tduration = animation.duration;\r\n\r\n\t\t}\r\n\r\n\t\treturn duration;\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.playAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.time = 0;\r\n\t\t\tanimation.active = true;\r\n\r\n\t\t} else {\r\n\r\n\t\t\tconsole.warn( \"THREE.MorphBlendMesh: animation[\" + name + \"] undefined in .playAnimation()\" );\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.stopAnimation = function ( name ) {\r\n\r\n\t\tvar animation = this.animationsMap[ name ];\r\n\r\n\t\tif ( animation ) {\r\n\r\n\t\t\tanimation.active = false;\r\n\r\n\t\t}\r\n\r\n\t};\r\n\r\n\tMorphBlendMesh.prototype.update = function ( delta ) {\r\n\r\n\t\tfor ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {\r\n\r\n\t\t\tvar animation = this.animationsList[ i ];\r\n\r\n\t\t\tif ( ! animation.active ) continue;\r\n\r\n\t\t\tvar frameTime = animation.duration / animation.length;\r\n\r\n\t\t\tanimation.time += animation.direction * delta;\r\n\r\n\t\t\tif ( animation.mirroredLoop ) {\r\n\r\n\t\t\t\tif ( animation.time > animation.duration || animation.time < 0 ) {\r\n\r\n\t\t\t\t\tanimation.direction *= - 1;\r\n\r\n\t\t\t\t\tif ( animation.time > animation.duration ) {\r\n\r\n\t\t\t\t\t\tanimation.time = animation.duration;\r\n\t\t\t\t\t\tanimation.directionBackwards = true;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif ( animation.time < 0 ) {\r\n\r\n\t\t\t\t\t\tanimation.time = 0;\r\n\t\t\t\t\t\tanimation.directionBackwards = false;\r\n\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tanimation.time = animation.time % animation.duration;\r\n\r\n\t\t\t\tif ( animation.time < 0 ) animation.time += animation.duration;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar keyframe = animation.start + _Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );\r\n\t\t\tvar weight = animation.weight;\r\n\r\n\t\t\tif ( keyframe !== animation.currentFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = 0;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ keyframe ] = 0;\r\n\r\n\t\t\t\tanimation.lastFrame = animation.currentFrame;\r\n\t\t\t\tanimation.currentFrame = keyframe;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tvar mix = ( animation.time % frameTime ) / frameTime;\r\n\r\n\t\t\tif ( animation.directionBackwards ) mix = 1 - mix;\r\n\r\n\t\t\tif ( animation.currentFrame !== animation.lastFrame ) {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = mix * weight;\r\n\t\t\t\tthis.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\tthis.morphTargetInfluences[ animation.currentFrame ] = weight;\r\n\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t};\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tfunction ImmediateRenderObject( material ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.material = material;\n\t\tthis.render = function ( renderCallback ) {};\n\n\t}\n\n\tImmediateRenderObject.prototype = Object.create( Object3D.prototype );\n\tImmediateRenderObject.prototype.constructor = ImmediateRenderObject;\n\n\tImmediateRenderObject.prototype.isImmediateRenderObject = true;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction VertexNormalsHelper( object, size, hex, linewidth ) {\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xff0000;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length * 3;\n\n\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\tnNormals = objGeometry.attributes.normal.count;\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\tVertexNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tVertexNormalsHelper.prototype.constructor = VertexNormalsHelper;\n\n\tVertexNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tvar keys = [ 'a', 'b', 'c' ];\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\t\tvar faces = objGeometry.faces;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\t\tfor ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tvar vertex = vertices[ face[ keys[ j ] ] ];\n\n\t\t\t\t\t\tvar normal = face.vertexNormals[ j ];\n\n\t\t\t\t\t\tv1.copy( vertex ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} else if ( objGeometry && objGeometry.isBufferGeometry ) {\n\n\t\t\t\tvar objPos = objGeometry.attributes.position;\n\n\t\t\t\tvar objNorm = objGeometry.attributes.normal;\n\n\t\t\t\tvar idx = 0;\n\n\t\t\t\t// for simplicity, ignore index and drawcalls, and render every normal\n\n\t\t\t\tfor ( var j = 0, jl = objPos.count; j < jl; j ++ ) {\n\n\t\t\t\t\tv1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );\n\n\t\t\t\t\tv2.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) );\n\n\t\t\t\t\tv2.applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\t\tidx = idx + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction SpotLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = [\n\t\t\t0, 0, 0, 0, 0, 1,\n\t\t\t0, 0, 0, 1, 0, 1,\n\t\t\t0, 0, 0, - 1, 0, 1,\n\t\t\t0, 0, 0, 0, 1, 1,\n\t\t\t0, 0, 0, 0, - 1, 1\n\t\t];\n\n\t\tfor ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {\n\n\t\t\tvar p1 = ( i / l ) * Math.PI * 2;\n\t\t\tvar p2 = ( j / l ) * Math.PI * 2;\n\n\t\t\tpositions.push(\n\t\t\t\tMath.cos( p1 ), Math.sin( p1 ), 1,\n\t\t\t\tMath.cos( p2 ), Math.sin( p2 ), 1\n\t\t\t);\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.cone = new LineSegments( geometry, material );\n\t\tthis.add( this.cone );\n\n\t\tthis.update();\n\n\t}\n\n\tSpotLightHelper.prototype = Object.create( Object3D.prototype );\n\tSpotLightHelper.prototype.constructor = SpotLightHelper;\n\n\tSpotLightHelper.prototype.dispose = function () {\n\n\t\tthis.cone.geometry.dispose();\n\t\tthis.cone.material.dispose();\n\n\t};\n\n\tSpotLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar coneLength = this.light.distance ? this.light.distance : 1000;\n\t\t\tvar coneWidth = coneLength * Math.tan( this.light.angle );\n\n\t\t\tthis.cone.scale.set( coneWidth, coneWidth, coneLength );\n\n\t\t\tvector.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\tthis.cone.lookAt( vector2.sub( vector ) );\n\n\t\t\tthis.cone.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author Sean Griffin / http://twitter.com/sgrif\n\t * @author Michael Guerrero / http://realitymeltdown.com\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author ikerr / http://verold.com\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction SkeletonHelper( object ) {\n\n\t\tthis.bones = this.getBoneList( object );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar color1 = new Color( 0, 0, 1 );\n\t\tvar color2 = new Color( 0, 1, 0 );\n\n\t\tfor ( var i = 0; i < this.bones.length; i ++ ) {\n\n\t\t\tvar bone = this.bones[ i ];\n\n\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tvertices.push( 0, 0, 0 );\n\t\t\t\tcolors.push( color1.r, color1.g, color1.b );\n\t\t\t\tcolors.push( color2.r, color2.g, color2.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.root = object;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.update();\n\n\t}\n\n\n\tSkeletonHelper.prototype = Object.create( LineSegments.prototype );\n\tSkeletonHelper.prototype.constructor = SkeletonHelper;\n\n\tSkeletonHelper.prototype.getBoneList = function( object ) {\n\n\t\tvar boneList = [];\n\n\t\tif ( object && object.isBone ) {\n\n\t\t\tboneList.push( object );\n\n\t\t}\n\n\t\tfor ( var i = 0; i < object.children.length; i ++ ) {\n\n\t\t\tboneList.push.apply( boneList, this.getBoneList( object.children[ i ] ) );\n\n\t\t}\n\n\t\treturn boneList;\n\n\t};\n\n\tSkeletonHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar boneMatrix = new Matrix4();\n\t\tvar matrixWorldInv = new Matrix4();\n\n\t\treturn function update() {\n\n\t\t\tvar geometry = this.geometry;\n\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\tmatrixWorldInv.getInverse( this.root.matrixWorld );\n\n\t\t\tfor ( var i = 0, j = 0; i < this.bones.length; i ++ ) {\n\n\t\t\t\tvar bone = this.bones[ i ];\n\n\t\t\t\tif ( bone.parent && bone.parent.isBone ) {\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tboneMatrix.multiplyMatrices( matrixWorldInv, bone.parent.matrixWorld );\n\t\t\t\t\tvector.setFromMatrixPosition( boneMatrix );\n\t\t\t\t\tposition.setXYZ( j + 1, vector.x, vector.y, vector.z );\n\n\t\t\t\t\tj += 2;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction PointLightHelper( light, sphereSize ) {\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar geometry = new SphereBufferGeometry( sphereSize, 4, 2 );\n\t\tvar material = new MeshBasicMaterial( { wireframe: true, fog: false } );\n\t\tmaterial.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\tMesh.call( this, geometry, material );\n\n\t\tthis.matrix = this.light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\t/*\n\t\tvar distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );\n\t\tvar distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );\n\n\t\tthis.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );\n\t\tthis.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );\n\n\t\tvar d = light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\n\t\tthis.add( this.lightDistance );\n\t\t*/\n\n\t}\n\n\tPointLightHelper.prototype = Object.create( Mesh.prototype );\n\tPointLightHelper.prototype.constructor = PointLightHelper;\n\n\tPointLightHelper.prototype.dispose = function () {\n\n\t\tthis.geometry.dispose();\n\t\tthis.material.dispose();\n\n\t};\n\n\tPointLightHelper.prototype.update = function () {\n\n\t\tthis.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t/*\n\t\tvar d = this.light.distance;\n\n\t\tif ( d === 0.0 ) {\n\n\t\t\tthis.lightDistance.visible = false;\n\n\t\t} else {\n\n\t\t\tthis.lightDistance.visible = true;\n\t\t\tthis.lightDistance.scale.set( d, d, d );\n\n\t\t}\n\t\t*/\n\n\t};\n\n\t/**\n\t * @author abelnation / http://github.com/abelnation\n\t * @author Mugen87 / http://github.com/Mugen87\n\t */\n\n\tfunction RectAreaLightHelper( light ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tvar materialFront = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false\n\t\t} );\n\n\t\tvar materialBack = new MeshBasicMaterial( {\n\t\t\tcolor: light.color,\n\t\t\tfog: false,\n\t\t\twireframe: true\n\t\t} );\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 6 * 3 ), 3 ) );\n\n\t\t// shows the \"front\" of the light, e.g. where light comes from\n\n\t\tthis.add( new Mesh( geometry, materialFront ) );\n\n\t\t// shows the \"back\" of the light, which does not emit light\n\n\t\tthis.add( new Mesh( geometry, materialBack ) );\n\n\t\tthis.update();\n\n\t}\n\n\tRectAreaLightHelper.prototype = Object.create( Object3D.prototype );\n\tRectAreaLightHelper.prototype.constructor = RectAreaLightHelper;\n\n\tRectAreaLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\t\tthis.children[ 1 ].geometry.dispose();\n\t\tthis.children[ 1 ].material.dispose();\n\n\t};\n\n\tRectAreaLightHelper.prototype.update = function () {\n\n\t\tvar vector1 = new Vector3();\n\t\tvar vector2 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh1 = this.children[ 0 ];\n\t\t\tvar mesh2 = this.children[ 1 ];\n\n\t\t\tif ( this.light.target ) {\n\n\t\t\t\tvector1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\t\tvector2.setFromMatrixPosition( this.light.target.matrixWorld );\n\n\t\t\t\tvar lookVec = vector2.clone().sub( vector1 );\n\t\t\t\tmesh1.lookAt( lookVec );\n\t\t\t\tmesh2.lookAt( lookVec );\n\n\t\t\t}\n\n\t\t\t// update materials\n\n\t\t\tmesh1.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tmesh2.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\t// calculate new dimensions of the helper\n\n\t\t\tvar hx = this.light.width * 0.5;\n\t\t\tvar hy = this.light.height * 0.5;\n\n\t\t\t// because the buffer attribute is shared over both geometries, we only have to update once\n\n\t\t\tvar position = mesh1.geometry.getAttribute( 'position' );\n\t\t\tvar array = position.array;\n\n\t\t\t// first face\n\n\t\t\tarray[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;\n\t\t\tarray[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;\n\t\t\tarray[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;\n\n\t\t\t// second face\n\n\t\t\tarray[ 9 ] = - hx; array[ 10 ] = hy; array[ 11 ] = 0;\n\t\t\tarray[ 12 ] = - hx; array[ 13 ] = - hy; array[ 14 ] = 0;\n\t\t\tarray[ 15 ] = hx; array[ 16 ] = - hy; array[ 17 ] = 0;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t */\n\n\tfunction HemisphereLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tvar geometry = new OctahedronBufferGeometry( size );\n\t\tgeometry.rotateY( Math.PI * 0.5 );\n\n\t\tvar material = new MeshBasicMaterial( { vertexColors: VertexColors, wireframe: true } );\n\n\t\tvar position = geometry.getAttribute( 'position' );\n\t\tvar colors = new Float32Array( position.count * 3 );\n\n\t\tgeometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) );\n\n\t\tthis.add( new Mesh( geometry, material ) );\n\n\t\tthis.update();\n\n\t}\n\n\tHemisphereLightHelper.prototype = Object.create( Object3D.prototype );\n\tHemisphereLightHelper.prototype.constructor = HemisphereLightHelper;\n\n\tHemisphereLightHelper.prototype.dispose = function () {\n\n\t\tthis.children[ 0 ].geometry.dispose();\n\t\tthis.children[ 0 ].material.dispose();\n\n\t};\n\n\tHemisphereLightHelper.prototype.update = function () {\n\n\t\tvar vector = new Vector3();\n\n\t\tvar color1 = new Color();\n\t\tvar color2 = new Color();\n\n\t\treturn function update() {\n\n\t\t\tvar mesh = this.children[ 0 ];\n\n\t\t\tvar colors = mesh.geometry.getAttribute( 'color' );\n\n\t\t\tcolor1.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\t\t\tcolor2.copy( this.light.groundColor ).multiplyScalar( this.light.intensity );\n\n\t\t\tfor ( var i = 0, l = colors.count; i < l; i ++ ) {\n\n\t\t\t\tvar color = ( i < ( l / 2 ) ) ? color1 : color2;\n\n\t\t\t\tcolors.setXYZ( i, color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t\tmesh.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );\n\n\t\t\tcolors.needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction GridHelper( size, divisions, color1, color2 ) {\n\n\t\tsize = size || 10;\n\t\tdivisions = divisions || 10;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar center = divisions / 2;\n\t\tvar step = size / divisions;\n\t\tvar halfSize = size / 2;\n\n\t\tvar vertices = [], colors = [];\n\n\t\tfor ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {\n\n\t\t\tvertices.push( - halfSize, 0, k, halfSize, 0, k );\n\t\t\tvertices.push( k, 0, - halfSize, k, 0, halfSize );\n\n\t\t\tvar color = i === center ? color1 : color2;\n\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\t\t\tcolor.toArray( colors, j ); j += 3;\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tGridHelper.prototype = Object.create( LineSegments.prototype );\n\tGridHelper.prototype.constructor = GridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author Mugen87 / http://github.com/Mugen87\n\t * @author Hectate / http://www.github.com/Hectate\n\t */\n\n\tfunction PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {\n\n\t\tradius = radius || 10;\n\t\tradials = radials || 16;\n\t\tcircles = circles || 8;\n\t\tdivisions = divisions || 64;\n\t\tcolor1 = new Color( color1 !== undefined ? color1 : 0x444444 );\n\t\tcolor2 = new Color( color2 !== undefined ? color2 : 0x888888 );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar x, z;\n\t\tvar v, i, j, r, color;\n\n\t\t// create the radials\n\n\t\tfor ( i = 0; i <= radials; i ++ ) {\n\n\t\t\tv = ( i / radials ) * ( Math.PI * 2 );\n\n\t\t\tx = Math.sin( v ) * radius;\n\t\t\tz = Math.cos( v ) * radius;\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tvertices.push( x, 0, z );\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tcolors.push( color.r, color.g, color.b );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t}\n\n\t\t// create the circles\n\n\t\tfor ( i = 0; i <= circles; i ++ ) {\n\n\t\t\tcolor = ( i & 1 ) ? color1 : color2;\n\n\t\t\tr = radius - ( radius / circles * i );\n\n\t\t\tfor ( j = 0; j < divisions; j ++ ) {\n\n\t\t\t\t// first vertex\n\n\t\t\t\tv = ( j / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t\t// second vertex\n\n\t\t\t\tv = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );\n\n\t\t\t\tx = Math.sin( v ) * r;\n\t\t\t\tz = Math.cos( v ) * r;\n\n\t\t\t\tvertices.push( x, 0, z );\n\t\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tPolarGridHelper.prototype = Object.create( LineSegments.prototype );\n\tPolarGridHelper.prototype.constructor = PolarGridHelper;\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t*/\n\n\tfunction FaceNormalsHelper( object, size, hex, linewidth ) {\n\n\t\t// FaceNormalsHelper only supports THREE.Geometry\n\n\t\tthis.object = object;\n\n\t\tthis.size = ( size !== undefined ) ? size : 1;\n\n\t\tvar color = ( hex !== undefined ) ? hex : 0xffff00;\n\n\t\tvar width = ( linewidth !== undefined ) ? linewidth : 1;\n\n\t\t//\n\n\t\tvar nNormals = 0;\n\n\t\tvar objGeometry = this.object.geometry;\n\n\t\tif ( objGeometry && objGeometry.isGeometry ) {\n\n\t\t\tnNormals = objGeometry.faces.length;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' );\n\n\t\t}\n\n\t\t//\n\n\t\tvar geometry = new BufferGeometry();\n\n\t\tvar positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );\n\n\t\tgeometry.addAttribute( 'position', positions );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) );\n\n\t\t//\n\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.update();\n\n\t}\n\n\tFaceNormalsHelper.prototype = Object.create( LineSegments.prototype );\n\tFaceNormalsHelper.prototype.constructor = FaceNormalsHelper;\n\n\tFaceNormalsHelper.prototype.update = ( function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar normalMatrix = new Matrix3();\n\n\t\treturn function update() {\n\n\t\t\tthis.object.updateMatrixWorld( true );\n\n\t\t\tnormalMatrix.getNormalMatrix( this.object.matrixWorld );\n\n\t\t\tvar matrixWorld = this.object.matrixWorld;\n\n\t\t\tvar position = this.geometry.attributes.position;\n\n\t\t\t//\n\n\t\t\tvar objGeometry = this.object.geometry;\n\n\t\t\tvar vertices = objGeometry.vertices;\n\n\t\t\tvar faces = objGeometry.faces;\n\n\t\t\tvar idx = 0;\n\n\t\t\tfor ( var i = 0, l = faces.length; i < l; i ++ ) {\n\n\t\t\t\tvar face = faces[ i ];\n\n\t\t\t\tvar normal = face.normal;\n\n\t\t\t\tv1.copy( vertices[ face.a ] )\n\t\t\t\t\t.add( vertices[ face.b ] )\n\t\t\t\t\t.add( vertices[ face.c ] )\n\t\t\t\t\t.divideScalar( 3 )\n\t\t\t\t\t.applyMatrix4( matrixWorld );\n\n\t\t\t\tv2.copy( normal ).applyMatrix3( normalMatrix ).normalize().multiplyScalar( this.size ).add( v1 );\n\n\t\t\t\tposition.setXYZ( idx, v1.x, v1.y, v1.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t\tposition.setXYZ( idx, v2.x, v2.y, v2.z );\n\n\t\t\t\tidx = idx + 1;\n\n\t\t\t}\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\treturn this;\n\n\t\t};\n\n\t}() );\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author mrdoob / http://mrdoob.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t */\n\n\tfunction DirectionalLightHelper( light, size ) {\n\n\t\tObject3D.call( this );\n\n\t\tthis.light = light;\n\t\tthis.light.updateMatrixWorld();\n\n\t\tthis.matrix = light.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tif ( size === undefined ) size = 1;\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [\n\t\t\t- size, size, 0,\n\t\t\t size, size, 0,\n\t\t\t size, - size, 0,\n\t\t\t- size, - size, 0,\n\t\t\t- size, size, 0\n\t\t], 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { fog: false } );\n\n\t\tthis.add( new Line( geometry, material ) );\n\n\t\tgeometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );\n\n\t\tthis.add( new Line( geometry, material ));\n\n\t\tthis.update();\n\n\t}\n\n\tDirectionalLightHelper.prototype = Object.create( Object3D.prototype );\n\tDirectionalLightHelper.prototype.constructor = DirectionalLightHelper;\n\n\tDirectionalLightHelper.prototype.dispose = function () {\n\n\t\tvar lightPlane = this.children[ 0 ];\n\t\tvar targetLine = this.children[ 1 ];\n\n\t\tlightPlane.geometry.dispose();\n\t\tlightPlane.material.dispose();\n\t\ttargetLine.geometry.dispose();\n\t\ttargetLine.material.dispose();\n\n\t};\n\n\tDirectionalLightHelper.prototype.update = function () {\n\n\t\tvar v1 = new Vector3();\n\t\tvar v2 = new Vector3();\n\t\tvar v3 = new Vector3();\n\n\t\treturn function update() {\n\n\t\t\tv1.setFromMatrixPosition( this.light.matrixWorld );\n\t\t\tv2.setFromMatrixPosition( this.light.target.matrixWorld );\n\t\t\tv3.subVectors( v2, v1 );\n\n\t\t\tvar lightPlane = this.children[ 0 ];\n\t\t\tvar targetLine = this.children[ 1 ];\n\n\t\t\tlightPlane.lookAt( v3 );\n\t\t\tlightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );\n\n\t\t\ttargetLine.lookAt( v3 );\n\t\t\ttargetLine.scale.z = v3.length();\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author Mugen87 / https://github.com/Mugen87\n\t *\n\t *\t- shows frustum, line of sight and up of the camera\n\t *\t- suitable for fast updates\n\t * \t- based on frustum visualization in lightgl.js shadowmap example\n\t *\t\thttp://evanw.github.com/lightgl.js/tests/shadowmap.html\n\t */\n\n\tfunction CameraHelper( camera ) {\n\n\t\tvar geometry = new BufferGeometry();\n\t\tvar material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } );\n\n\t\tvar vertices = [];\n\t\tvar colors = [];\n\n\t\tvar pointMap = {};\n\n\t\t// colors\n\n\t\tvar colorFrustum = new Color( 0xffaa00 );\n\t\tvar colorCone = new Color( 0xff0000 );\n\t\tvar colorUp = new Color( 0x00aaff );\n\t\tvar colorTarget = new Color( 0xffffff );\n\t\tvar colorCross = new Color( 0x333333 );\n\n\t\t// near\n\n\t\taddLine( \"n1\", \"n2\", colorFrustum );\n\t\taddLine( \"n2\", \"n4\", colorFrustum );\n\t\taddLine( \"n4\", \"n3\", colorFrustum );\n\t\taddLine( \"n3\", \"n1\", colorFrustum );\n\n\t\t// far\n\n\t\taddLine( \"f1\", \"f2\", colorFrustum );\n\t\taddLine( \"f2\", \"f4\", colorFrustum );\n\t\taddLine( \"f4\", \"f3\", colorFrustum );\n\t\taddLine( \"f3\", \"f1\", colorFrustum );\n\n\t\t// sides\n\n\t\taddLine( \"n1\", \"f1\", colorFrustum );\n\t\taddLine( \"n2\", \"f2\", colorFrustum );\n\t\taddLine( \"n3\", \"f3\", colorFrustum );\n\t\taddLine( \"n4\", \"f4\", colorFrustum );\n\n\t\t// cone\n\n\t\taddLine( \"p\", \"n1\", colorCone );\n\t\taddLine( \"p\", \"n2\", colorCone );\n\t\taddLine( \"p\", \"n3\", colorCone );\n\t\taddLine( \"p\", \"n4\", colorCone );\n\n\t\t// up\n\n\t\taddLine( \"u1\", \"u2\", colorUp );\n\t\taddLine( \"u2\", \"u3\", colorUp );\n\t\taddLine( \"u3\", \"u1\", colorUp );\n\n\t\t// target\n\n\t\taddLine( \"c\", \"t\", colorTarget );\n\t\taddLine( \"p\", \"c\", colorCross );\n\n\t\t// cross\n\n\t\taddLine( \"cn1\", \"cn2\", colorCross );\n\t\taddLine( \"cn3\", \"cn4\", colorCross );\n\n\t\taddLine( \"cf1\", \"cf2\", colorCross );\n\t\taddLine( \"cf3\", \"cf4\", colorCross );\n\n\t\tfunction addLine( a, b, color ) {\n\n\t\t\taddPoint( a, color );\n\t\t\taddPoint( b, color );\n\n\t\t}\n\n\t\tfunction addPoint( id, color ) {\n\n\t\t\tvertices.push( 0, 0, 0 );\n\t\t\tcolors.push( color.r, color.g, color.b );\n\n\t\t\tif ( pointMap[ id ] === undefined ) {\n\n\t\t\t\tpointMap[ id ] = [];\n\n\t\t\t}\n\n\t\t\tpointMap[ id ].push( ( vertices.length / 3 ) - 1 );\n\n\t\t}\n\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t\tthis.camera = camera;\n\t\tif ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\n\t}\n\n\tCameraHelper.prototype = Object.create( LineSegments.prototype );\n\tCameraHelper.prototype.constructor = CameraHelper;\n\n\tCameraHelper.prototype.update = function () {\n\n\t\tvar geometry, pointMap;\n\n\t\tvar vector = new Vector3();\n\t\tvar camera = new Camera();\n\n\t\tfunction setPoint( point, x, y, z ) {\n\n\t\t\tvector.set( x, y, z ).unproject( camera );\n\n\t\t\tvar points = pointMap[ point ];\n\n\t\t\tif ( points !== undefined ) {\n\n\t\t\t\tvar position = geometry.getAttribute( 'position' );\n\n\t\t\t\tfor ( var i = 0, l = points.length; i < l; i ++ ) {\n\n\t\t\t\t\tposition.setXYZ( points[ i ], vector.x, vector.y, vector.z );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn function update() {\n\n\t\t\tgeometry = this.geometry;\n\t\t\tpointMap = this.pointMap;\n\n\t\t\tvar w = 1, h = 1;\n\n\t\t\t// we need just camera projection matrix\n\t\t\t// world matrix must be identity\n\n\t\t\tcamera.projectionMatrix.copy( this.camera.projectionMatrix );\n\n\t\t\t// center / target\n\n\t\t\tsetPoint( \"c\", 0, 0, - 1 );\n\t\t\tsetPoint( \"t\", 0, 0, 1 );\n\n\t\t\t// near\n\n\t\t\tsetPoint( \"n1\", - w, - h, - 1 );\n\t\t\tsetPoint( \"n2\", w, - h, - 1 );\n\t\t\tsetPoint( \"n3\", - w, h, - 1 );\n\t\t\tsetPoint( \"n4\", w, h, - 1 );\n\n\t\t\t// far\n\n\t\t\tsetPoint( \"f1\", - w, - h, 1 );\n\t\t\tsetPoint( \"f2\", w, - h, 1 );\n\t\t\tsetPoint( \"f3\", - w, h, 1 );\n\t\t\tsetPoint( \"f4\", w, h, 1 );\n\n\t\t\t// up\n\n\t\t\tsetPoint( \"u1\", w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u2\", - w * 0.7, h * 1.1, - 1 );\n\t\t\tsetPoint( \"u3\", 0, h * 2, - 1 );\n\n\t\t\t// cross\n\n\t\t\tsetPoint( \"cf1\", - w, 0, 1 );\n\t\t\tsetPoint( \"cf2\", w, 0, 1 );\n\t\t\tsetPoint( \"cf3\", 0, - h, 1 );\n\t\t\tsetPoint( \"cf4\", 0, h, 1 );\n\n\t\t\tsetPoint( \"cn1\", - w, 0, - 1 );\n\t\t\tsetPoint( \"cn2\", w, 0, - 1 );\n\t\t\tsetPoint( \"cn3\", 0, - h, - 1 );\n\t\t\tsetPoint( \"cn4\", 0, h, - 1 );\n\n\t\t\tgeometry.getAttribute( 'position' ).needsUpdate = true;\n\n\t\t};\n\n\t}();\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction BoxHelper( object, color ) {\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\n\t\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\t\tvar positions = new Float32Array( 8 * 3 );\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.setIndex( new BufferAttribute( indices, 1 ) );\n\t\tgeometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) );\n\n\t\tLineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );\n\n\t\tif ( object !== undefined ) {\n\n\t\t\tthis.update( object );\n\n\t\t}\n\n\t}\n\n\tBoxHelper.prototype = Object.create( LineSegments.prototype );\n\tBoxHelper.prototype.constructor = BoxHelper;\n\n\tBoxHelper.prototype.update = ( function () {\n\n\t\tvar box = new Box3();\n\n\t\treturn function update( object ) {\n\n\t\t\tif ( object && object.isBox3 ) {\n\n\t\t\t\tbox.copy( object );\n\n\t\t\t} else {\n\n\t\t\t\tbox.setFromObject( object );\n\n\t\t\t}\n\n\t\t\tif ( box.isEmpty() ) return;\n\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\n\t\t\t/*\n\t\t\t 5____4\n\t\t\t1/___0/|\n\t\t\t| 6__|_7\n\t\t\t2/___3/\n\n\t\t\t0: max.x, max.y, max.z\n\t\t\t1: min.x, max.y, max.z\n\t\t\t2: min.x, min.y, max.z\n\t\t\t3: max.x, min.y, max.z\n\t\t\t4: max.x, max.y, min.z\n\t\t\t5: min.x, max.y, min.z\n\t\t\t6: min.x, min.y, min.z\n\t\t\t7: max.x, min.y, min.z\n\t\t\t*/\n\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\n\t\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\t\tposition.needsUpdate = true;\n\n\t\t\tthis.geometry.computeBoundingSphere();\n\n\t\t};\n\n\t} )();\n\n\t/**\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author zz85 / http://github.com/zz85\n\t * @author bhouston / http://clara.io\n\t *\n\t * Creates an arrow for visualizing directions\n\t *\n\t * Parameters:\n\t * dir - Vector3\n\t * origin - Vector3\n\t * length - Number\n\t * color - color in hex value\n\t * headLength - Number\n\t * headWidth - Number\n\t */\n\n\tvar lineGeometry;\n\tvar coneGeometry;\n\n\tfunction ArrowHelper( dir, origin, length, color, headLength, headWidth ) {\n\n\t\t// dir is assumed to be normalized\n\n\t\tObject3D.call( this );\n\n\t\tif ( color === undefined ) color = 0xffff00;\n\t\tif ( length === undefined ) length = 1;\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tif ( lineGeometry === undefined ) {\n\n\t\t\tlineGeometry = new BufferGeometry();\n\t\t\tlineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );\n\n\t\t\tconeGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );\n\t\t\tconeGeometry.translate( 0, - 0.5, 0 );\n\n\t\t}\n\n\t\tthis.position.copy( origin );\n\n\t\tthis.line = new Line( lineGeometry, new LineBasicMaterial( { color: color } ) );\n\t\tthis.line.matrixAutoUpdate = false;\n\t\tthis.add( this.line );\n\n\t\tthis.cone = new Mesh( coneGeometry, new MeshBasicMaterial( { color: color } ) );\n\t\tthis.cone.matrixAutoUpdate = false;\n\t\tthis.add( this.cone );\n\n\t\tthis.setDirection( dir );\n\t\tthis.setLength( length, headLength, headWidth );\n\n\t}\n\n\tArrowHelper.prototype = Object.create( Object3D.prototype );\n\tArrowHelper.prototype.constructor = ArrowHelper;\n\n\tArrowHelper.prototype.setDirection = ( function () {\n\n\t\tvar axis = new Vector3();\n\t\tvar radians;\n\n\t\treturn function setDirection( dir ) {\n\n\t\t\t// dir is assumed to be normalized\n\n\t\t\tif ( dir.y > 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 0, 0, 0, 1 );\n\n\t\t\t} else if ( dir.y < - 0.99999 ) {\n\n\t\t\t\tthis.quaternion.set( 1, 0, 0, 0 );\n\n\t\t\t} else {\n\n\t\t\t\taxis.set( dir.z, 0, - dir.x ).normalize();\n\n\t\t\t\tradians = Math.acos( dir.y );\n\n\t\t\t\tthis.quaternion.setFromAxisAngle( axis, radians );\n\n\t\t\t}\n\n\t\t};\n\n\t}() );\n\n\tArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {\n\n\t\tif ( headLength === undefined ) headLength = 0.2 * length;\n\t\tif ( headWidth === undefined ) headWidth = 0.2 * headLength;\n\n\t\tthis.line.scale.set( 1, Math.max( 0, length - headLength ), 1 );\n\t\tthis.line.updateMatrix();\n\n\t\tthis.cone.scale.set( headWidth, headLength, headWidth );\n\t\tthis.cone.position.y = length;\n\t\tthis.cone.updateMatrix();\n\n\t};\n\n\tArrowHelper.prototype.setColor = function ( color ) {\n\n\t\tthis.line.material.color.copy( color );\n\t\tthis.cone.material.color.copy( color );\n\n\t};\n\n\t/**\n\t * @author sroucheray / http://sroucheray.org/\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction AxisHelper( size ) {\n\n\t\tsize = size || 1;\n\n\t\tvar vertices = [\n\t\t\t0, 0, 0, size, 0, 0,\n\t\t\t0, 0, 0, 0, size, 0,\n\t\t\t0, 0, 0, 0, 0, size\n\t\t];\n\n\t\tvar colors = [\n\t\t\t1, 0, 0, 1, 0.6, 0,\n\t\t\t0, 1, 0, 0.6, 1, 0,\n\t\t\t0, 0, 1, 0, 0.6, 1\n\t\t];\n\n\t\tvar geometry = new BufferGeometry();\n\t\tgeometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );\n\t\tgeometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );\n\n\t\tvar material = new LineBasicMaterial( { vertexColors: VertexColors } );\n\n\t\tLineSegments.call( this, geometry, material );\n\n\t}\n\n\tAxisHelper.prototype = Object.create( LineSegments.prototype );\n\tAxisHelper.prototype.constructor = AxisHelper;\n\n\t/**\n\t * @author zz85 https://github.com/zz85\n\t *\n\t * Centripetal CatmullRom Curve - which is useful for avoiding\n\t * cusps and self-intersections in non-uniform catmull rom curves.\n\t * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf\n\t *\n\t * curve.type accepts centripetal(default), chordal and catmullrom\n\t * curve.tension is used for catmullrom which defaults to 0.5\n\t */\n\n\n\t/*\n\tBased on an optimized c++ solution in\n\t - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/\n\t - http://ideone.com/NoEbVM\n\n\tThis CubicPoly class could be used for reusing some variables and calculations,\n\tbut for three.js curve use, it could be possible inlined and flatten into a single function call\n\twhich can be placed in CurveUtils.\n\t*/\n\n\tfunction CubicPoly() {\n\n\t\tvar c0 = 0, c1 = 0, c2 = 0, c3 = 0;\n\n\t\t/*\n\t\t * Compute coefficients for a cubic polynomial\n\t\t * p(s) = c0 + c1*s + c2*s^2 + c3*s^3\n\t\t * such that\n\t\t * p(0) = x0, p(1) = x1\n\t\t * and\n\t\t * p'(0) = t0, p'(1) = t1.\n\t\t */\n\t\tfunction init( x0, x1, t0, t1 ) {\n\n\t\t\tc0 = x0;\n\t\t\tc1 = t0;\n\t\t\tc2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;\n\t\t\tc3 = 2 * x0 - 2 * x1 + t0 + t1;\n\n\t\t}\n\n\t\treturn {\n\n\t\t\tinitCatmullRom: function ( x0, x1, x2, x3, tension ) {\n\n\t\t\t\tinit( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );\n\n\t\t\t},\n\n\t\t\tinitNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {\n\n\t\t\t\t// compute tangents when parameterized in [t1,t2]\n\t\t\t\tvar t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;\n\t\t\t\tvar t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;\n\n\t\t\t\t// rescale tangents for parametrization in [0,1]\n\t\t\t\tt1 *= dt1;\n\t\t\t\tt2 *= dt1;\n\n\t\t\t\tinit( x1, x2, t1, t2 );\n\n\t\t\t},\n\n\t\t\tcalc: function ( t ) {\n\n\t\t\t\tvar t2 = t * t;\n\t\t\t\tvar t3 = t2 * t;\n\t\t\t\treturn c0 + c1 * t + c2 * t2 + c3 * t3;\n\n\t\t\t}\n\n\t\t};\n\n\t}\n\n\t//\n\n\tvar tmp = new Vector3();\n\tvar px = new CubicPoly();\n\tvar py = new CubicPoly();\n\tvar pz = new CubicPoly();\n\n\tfunction CatmullRomCurve3( p /* array of Vector3 */ ) {\n\n\t\tthis.points = p || [];\n\t\tthis.closed = false;\n\n\t}\n\n\tCatmullRomCurve3.prototype = Object.create( Curve.prototype );\n\tCatmullRomCurve3.prototype.constructor = CatmullRomCurve3;\n\n\tCatmullRomCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar points = this.points;\n\t\tvar l = points.length;\n\n\t\tif ( l < 2 ) console.log( 'duh, you need at least 2 points' );\n\n\t\tvar point = ( l - ( this.closed ? 0 : 1 ) ) * t;\n\t\tvar intPoint = Math.floor( point );\n\t\tvar weight = point - intPoint;\n\n\t\tif ( this.closed ) {\n\n\t\t\tintPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;\n\n\t\t} else if ( weight === 0 && intPoint === l - 1 ) {\n\n\t\t\tintPoint = l - 2;\n\t\t\tweight = 1;\n\n\t\t}\n\n\t\tvar p0, p1, p2, p3; // 4 points\n\n\t\tif ( this.closed || intPoint > 0 ) {\n\n\t\t\tp0 = points[ ( intPoint - 1 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate first point\n\t\t\ttmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );\n\t\t\tp0 = tmp;\n\n\t\t}\n\n\t\tp1 = points[ intPoint % l ];\n\t\tp2 = points[ ( intPoint + 1 ) % l ];\n\n\t\tif ( this.closed || intPoint + 2 < l ) {\n\n\t\t\tp3 = points[ ( intPoint + 2 ) % l ];\n\n\t\t} else {\n\n\t\t\t// extrapolate last point\n\t\t\ttmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );\n\t\t\tp3 = tmp;\n\n\t\t}\n\n\t\tif ( this.type === undefined || this.type === 'centripetal' || this.type === 'chordal' ) {\n\n\t\t\t// init Centripetal / Chordal Catmull-Rom\n\t\t\tvar pow = this.type === 'chordal' ? 0.5 : 0.25;\n\t\t\tvar dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );\n\t\t\tvar dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );\n\t\t\tvar dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );\n\n\t\t\t// safety check for repeated points\n\t\t\tif ( dt1 < 1e-4 ) dt1 = 1.0;\n\t\t\tif ( dt0 < 1e-4 ) dt0 = dt1;\n\t\t\tif ( dt2 < 1e-4 ) dt2 = dt1;\n\n\t\t\tpx.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );\n\t\t\tpy.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );\n\t\t\tpz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );\n\n\t\t} else if ( this.type === 'catmullrom' ) {\n\n\t\t\tvar tension = this.tension !== undefined ? this.tension : 0.5;\n\t\t\tpx.initCatmullRom( p0.x, p1.x, p2.x, p3.x, tension );\n\t\t\tpy.initCatmullRom( p0.y, p1.y, p2.y, p3.y, tension );\n\t\t\tpz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, tension );\n\n\t\t}\n\n\t\treturn new Vector3( px.calc( weight ), py.calc( weight ), pz.calc( weight ) );\n\n\t};\n\n\tfunction CubicBezierCurve3( v0, v1, v2, v3 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\t\tthis.v3 = v3;\n\n\t}\n\n\tCubicBezierCurve3.prototype = Object.create( Curve.prototype );\n\tCubicBezierCurve3.prototype.constructor = CubicBezierCurve3;\n\n\tCubicBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;\n\n\t\treturn new Vector3(\n\t\t\tCubicBezier( t, v0.x, v1.x, v2.x, v3.x ),\n\t\t\tCubicBezier( t, v0.y, v1.y, v2.y, v3.y ),\n\t\t\tCubicBezier( t, v0.z, v1.z, v2.z, v3.z )\n\t\t);\n\n\t};\n\n\tfunction QuadraticBezierCurve3( v0, v1, v2 ) {\n\n\t\tthis.v0 = v0;\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tQuadraticBezierCurve3.prototype = Object.create( Curve.prototype );\n\tQuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;\n\n\tQuadraticBezierCurve3.prototype.getPoint = function ( t ) {\n\n\t\tvar v0 = this.v0, v1 = this.v1, v2 = this.v2;\n\n\t\treturn new Vector3(\n\t\t\tQuadraticBezier( t, v0.x, v1.x, v2.x ),\n\t\t\tQuadraticBezier( t, v0.y, v1.y, v2.y ),\n\t\t\tQuadraticBezier( t, v0.z, v1.z, v2.z )\n\t\t);\n\n\t};\n\n\tfunction LineCurve3( v1, v2 ) {\n\n\t\tthis.v1 = v1;\n\t\tthis.v2 = v2;\n\n\t}\n\n\tLineCurve3.prototype = Object.create( Curve.prototype );\n\tLineCurve3.prototype.constructor = LineCurve3;\n\n\tLineCurve3.prototype.getPoint = function ( t ) {\n\n\t\tif ( t === 1 ) {\n\n\t\t\treturn this.v2.clone();\n\n\t\t}\n\n\t\tvar vector = new Vector3();\n\n\t\tvector.subVectors( this.v2, this.v1 ); // diff\n\t\tvector.multiplyScalar( t );\n\t\tvector.add( this.v1 );\n\n\t\treturn vector;\n\n\t};\n\n\tfunction ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {\n\n\t\tEllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );\n\n\t}\n\n\tArcCurve.prototype = Object.create( EllipseCurve.prototype );\n\tArcCurve.prototype.constructor = ArcCurve;\n\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\n\tvar SceneUtils = {\n\n\t\tcreateMultiMaterialObject: function ( geometry, materials ) {\n\n\t\t\tvar group = new Group();\n\n\t\t\tfor ( var i = 0, l = materials.length; i < l; i ++ ) {\n\n\t\t\t\tgroup.add( new Mesh( geometry, materials[ i ] ) );\n\n\t\t\t}\n\n\t\t\treturn group;\n\n\t\t},\n\n\t\tdetach: function ( child, parent, scene ) {\n\n\t\t\tchild.applyMatrix( parent.matrixWorld );\n\t\t\tparent.remove( child );\n\t\t\tscene.add( child );\n\n\t\t},\n\n\t\tattach: function ( child, scene, parent ) {\n\n\t\t\tvar matrixWorldInverse = new Matrix4();\n\t\t\tmatrixWorldInverse.getInverse( parent.matrixWorld );\n\t\t\tchild.applyMatrix( matrixWorldInverse );\n\n\t\t\tscene.remove( child );\n\t\t\tparent.add( child );\n\n\t\t}\n\n\t};\n\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\n\tfunction Face4( a, b, c, d, normal, color, materialIndex ) {\n\n\t\tconsole.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );\n\t\treturn new Face3( a, b, c, normal, color, materialIndex );\n\n\t}\n\n\tvar LineStrip = 0;\n\n\tvar LinePieces = 1;\n\n\tfunction MeshFaceMaterial( materials ) {\n\n\t\tconsole.warn( 'THREE.MeshFaceMaterial has been renamed to THREE.MultiMaterial.' );\n\t\treturn new MultiMaterial( materials );\n\n\t}\n\n\tfunction PointCloud( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction Particle( material ) {\n\n\t\tconsole.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );\n\t\treturn new Sprite( material );\n\n\t}\n\n\tfunction ParticleSystem( geometry, material ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );\n\t\treturn new Points( geometry, material );\n\n\t}\n\n\tfunction PointCloudMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleBasicMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction ParticleSystemMaterial( parameters ) {\n\n\t\tconsole.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );\n\t\treturn new PointsMaterial( parameters );\n\n\t}\n\n\tfunction Vertex( x, y, z ) {\n\n\t\tconsole.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );\n\t\treturn new Vector3( x, y, z );\n\n\t}\n\n\t//\n\n\tfunction DynamicBufferAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' );\n\t\treturn new BufferAttribute( array, itemSize ).setDynamic( true );\n\n\t}\n\n\tfunction Int8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );\n\t\treturn new Int8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );\n\t\treturn new Uint8BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint8ClampedAttribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );\n\t\treturn new Uint8ClampedBufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );\n\t\treturn new Int16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint16Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );\n\t\treturn new Uint16BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Int32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );\n\t\treturn new Int32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Uint32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );\n\t\treturn new Uint32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float32Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );\n\t\treturn new Float32BufferAttribute( array, itemSize );\n\n\t}\n\n\tfunction Float64Attribute( array, itemSize ) {\n\n\t\tconsole.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );\n\t\treturn new Float64BufferAttribute( array, itemSize );\n\n\t}\n\n\t//\n\n\tCurve.create = function ( construct, getPoint ) {\n\n\t\tconsole.log( 'THREE.Curve.create() has been deprecated' );\n\n\t\tconstruct.prototype = Object.create( Curve.prototype );\n\t\tconstruct.prototype.constructor = construct;\n\t\tconstruct.prototype.getPoint = getPoint;\n\n\t\treturn construct;\n\n\t};\n\n\t//\n\n\tfunction ClosedSplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\t\tthis.closed = true;\n\n\t}\n\n\tClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction SplineCurve3( points ) {\n\n\t\tconsole.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\t//\n\n\tfunction Spline( points ) {\n\n\t\tconsole.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );\n\n\t\tCatmullRomCurve3.call( this, points );\n\t\tthis.type = 'catmullrom';\n\n\t}\n\n\tSpline.prototype = Object.create( CatmullRomCurve3.prototype );\n\n\tObject.assign( Spline.prototype, {\n\n\t\tinitFromArray: function ( a ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .initFromArray() has been removed.' );\n\n\t\t},\n\t\tgetControlPointsArray: function ( optionalTarget ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );\n\n\t\t},\n\t\treparametrizeByArcLength: function ( samplingCoef ) {\n\n\t\t\tconsole.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\t//\n\tfunction BoundingBoxHelper( object, color ) {\n\n\t\tconsole.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );\n\t\treturn new BoxHelper( object, color );\n\n\t}\n\n\tfunction EdgesHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );\n\t\treturn new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\tGridHelper.prototype.setColors = function () {\n\n\t\tconsole.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );\n\n\t};\n\n\tfunction WireframeHelper( object, hex ) {\n\n\t\tconsole.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );\n\t\treturn new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );\n\n\t}\n\n\t//\n\n\tfunction XHRLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );\n\t\treturn new FileLoader( manager );\n\n\t}\n\n\tfunction BinaryTextureLoader( manager ) {\n\n\t\tconsole.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );\n\t\treturn new DataTextureLoader( manager );\n\n\t}\n\n\t//\n\n\tObject.assign( Box2.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tObject.assign( Box3.prototype, {\n\n\t\tcenter: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );\n\t\t\treturn this.getCenter( optionalTarget );\n\n\t\t},\n\t\tempty: function () {\n\n\t\t\tconsole.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );\n\t\t\treturn this.isEmpty();\n\n\t\t},\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t},\n\t\tsize: function ( optionalTarget ) {\n\n\t\t\tconsole.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );\n\t\t\treturn this.getSize( optionalTarget );\n\n\t\t}\n\t} );\n\n\tLine3.prototype.center = function ( optionalTarget ) {\n\n\t\tconsole.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );\n\t\treturn this.getCenter( optionalTarget );\n\n\t};\n\n\t_Math.random16 = function () {\n\n\t\tconsole.warn( 'THREE.Math.random16() has been deprecated. Use Math.random() instead.' );\n\t\treturn Math.random();\n\n\t};\n\n\tObject.assign( Matrix3.prototype, {\n\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix3( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Matrix4.prototype, {\n\n\t\textractPosition: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );\n\t\t\treturn this.copyPosition( m );\n\n\t\t},\n\t\tflattenToArrayOffset: function ( array, offset ) {\n\n\t\t\tconsole.warn( \"THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.\" );\n\t\t\treturn this.toArray( array, offset );\n\n\t\t},\n\t\tgetPosition: function () {\n\n\t\t\tvar v1;\n\n\t\t\treturn function getPosition() {\n\n\t\t\t\tif ( v1 === undefined ) v1 = new Vector3();\n\t\t\t\tconsole.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );\n\t\t\t\treturn v1.setFromMatrixColumn( this, 3 );\n\n\t\t\t};\n\n\t\t}(),\n\t\tsetRotationFromQuaternion: function ( q ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );\n\t\t\treturn this.makeRotationFromQuaternion( q );\n\n\t\t},\n\t\tmultiplyVector3: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector4: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\tmultiplyVector3Array: function ( a ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' );\n\t\t\treturn this.applyToVector3Array( a );\n\n\t\t},\n\t\trotateAxis: function ( v ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );\n\t\t\tv.transformDirection( this );\n\n\t\t},\n\t\tcrossVector: function ( vector ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );\n\t\t\treturn vector.applyMatrix4( this );\n\n\t\t},\n\t\ttranslate: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .translate() has been removed.' );\n\n\t\t},\n\t\trotateX: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateX() has been removed.' );\n\n\t\t},\n\t\trotateY: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateY() has been removed.' );\n\n\t\t},\n\t\trotateZ: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateZ() has been removed.' );\n\n\t\t},\n\t\trotateByAxis: function () {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );\n\n\t\t},\n\t\tapplyToBuffer: function( buffer, offset, length ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' );\n\t\t\treturn this.applyToBufferAttribute( buffer );\n\n\t\t},\n\t\tapplyToVector3Array: function( array, offset, length ) {\n\n\t\t\tconsole.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );\n\n\t\t},\n\t\tmakeFrustum: function( left, right, bottom, top, near, far ) {\n\n\t\t\tconsole.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );\n\t\t\treturn this.makePerspective( left, right, top, bottom, near, far );\n\n\t\t}\n\n\t} );\n\n\tPlane.prototype.isIntersectionLine = function ( line ) {\n\n\t\tconsole.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );\n\t\treturn this.intersectsLine( line );\n\n\t};\n\n\tQuaternion.prototype.multiplyVector3 = function ( vector ) {\n\n\t\tconsole.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );\n\t\treturn vector.applyQuaternion( this );\n\n\t};\n\n\tObject.assign( Ray.prototype, {\n\n\t\tisIntersectionBox: function ( box ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );\n\t\t\treturn this.intersectsBox( box );\n\n\t\t},\n\t\tisIntersectionPlane: function ( plane ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );\n\t\t\treturn this.intersectsPlane( plane );\n\n\t\t},\n\t\tisIntersectionSphere: function ( sphere ) {\n\n\t\t\tconsole.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );\n\t\t\treturn this.intersectsSphere( sphere );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Shape.prototype, {\n\n\t\textrude: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );\n\t\t\treturn new ExtrudeGeometry( this, options );\n\n\t\t},\n\t\tmakeGeometry: function ( options ) {\n\n\t\t\tconsole.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );\n\t\t\treturn new ShapeGeometry( this, options );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector2.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector3.prototype, {\n\n\t\tsetEulerFromRotationMatrix: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );\n\n\t\t},\n\t\tsetEulerFromQuaternion: function () {\n\n\t\t\tconsole.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );\n\n\t\t},\n\t\tgetPositionFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );\n\t\t\treturn this.setFromMatrixPosition( m );\n\n\t\t},\n\t\tgetScaleFromMatrix: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );\n\t\t\treturn this.setFromMatrixScale( m );\n\n\t\t},\n\t\tgetColumnFromMatrix: function ( index, matrix ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );\n\t\t\treturn this.setFromMatrixColumn( matrix, index );\n\n\t\t},\n\t\tapplyProjection: function ( m ) {\n\n\t\t\tconsole.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );\n\t\t\treturn this.applyMatrix4( m );\n\n\t\t},\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\tObject.assign( Vector4.prototype, {\n\n\t\tfromAttribute: function ( attribute, index, offset ) {\n\n\t\t\tconsole.error( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );\n\t\t\treturn this.fromBufferAttribute( attribute, index, offset );\n\n\t\t}\n\n\t} );\n\n\t//\n\n\tGeometry.prototype.computeTangents = function () {\n\n\t\tconsole.warn( 'THREE.Geometry: .computeTangents() has been removed.' );\n\n\t};\n\n\tObject.assign( Object3D.prototype, {\n\n\t\tgetChildByName: function ( name ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );\n\t\t\treturn this.getObjectByName( name );\n\n\t\t},\n\t\trenderDepth: function () {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );\n\n\t\t},\n\t\ttranslate: function ( distance, axis ) {\n\n\t\t\tconsole.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );\n\t\t\treturn this.translateOnAxis( axis, distance );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( Object3D.prototype, {\n\n\t\teulerOrder: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\treturn this.rotation.order;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );\n\t\t\t\tthis.rotation.order = value;\n\n\t\t\t}\n\t\t},\n\t\tuseQuaternion: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( LOD.prototype, {\n\n\t\tobjects: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.LOD: .objects has been renamed to .levels.' );\n\t\t\t\treturn this.levels;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tPerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {\n\n\t\tconsole.warn( \"THREE.PerspectiveCamera.setLens is deprecated. \" +\n\t\t\t\t\"Use .setFocalLength and .filmGauge for a photographic setup.\" );\n\n\t\tif ( filmGauge !== undefined ) this.filmGauge = filmGauge;\n\t\tthis.setFocalLength( focalLength );\n\n\t};\n\n\t//\n\n\tObject.defineProperties( Light.prototype, {\n\t\tonlyShadow: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .onlyShadow has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFov: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );\n\t\t\t\tthis.shadow.camera.fov = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraLeft: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );\n\t\t\t\tthis.shadow.camera.left = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraRight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );\n\t\t\t\tthis.shadow.camera.right = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraTop: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );\n\t\t\t\tthis.shadow.camera.top = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraBottom: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );\n\t\t\t\tthis.shadow.camera.bottom = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraNear: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );\n\t\t\t\tthis.shadow.camera.near = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraFar: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );\n\t\t\t\tthis.shadow.camera.far = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowCameraVisible: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowBias: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );\n\t\t\t\tthis.shadow.bias = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowDarkness: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowDarkness has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\tshadowMapWidth: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );\n\t\t\t\tthis.shadow.mapSize.width = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapHeight: {\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );\n\t\t\t\tthis.shadow.mapSize.height = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\t//\n\n\tObject.defineProperties( BufferAttribute.prototype, {\n\n\t\tlength: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );\n\t\t\t\treturn this.array.length;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.assign( BufferGeometry.prototype, {\n\n\t\taddIndex: function ( index ) {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );\n\t\t\tthis.setIndex( index );\n\n\t\t},\n\t\taddDrawCall: function ( start, count, indexOffset ) {\n\n\t\t\tif ( indexOffset !== undefined ) {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );\n\n\t\t\t}\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );\n\t\t\tthis.addGroup( start, count );\n\n\t\t},\n\t\tclearDrawCalls: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );\n\t\t\tthis.clearGroups();\n\n\t\t},\n\t\tcomputeTangents: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );\n\n\t\t},\n\t\tcomputeOffsets: function () {\n\n\t\t\tconsole.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( BufferGeometry.prototype, {\n\n\t\tdrawcalls: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t},\n\t\toffsets: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );\n\t\t\t\treturn this.groups;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Uniform.prototype, {\n\n\t\tdynamic: {\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );\n\n\t\t\t}\n\t\t},\n\t\tonUpdate: {\n\t\t\tvalue: function () {\n\n\t\t\t\tconsole.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );\n\t\t\t\treturn this;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( Material.prototype, {\n\n\t\twrapAround: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapAround has been removed.' );\n\n\t\t\t}\n\t\t},\n\t\twrapRGB: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.' + this.type + ': .wrapRGB has been removed.' );\n\t\t\t\treturn new Color();\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( MeshPhongMaterial.prototype, {\n\n\t\tmetal: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );\n\t\t\t\treturn false;\n\n\t\t\t},\n\t\t\tset: function () {\n\n\t\t\t\tconsole.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( ShaderMaterial.prototype, {\n\n\t\tderivatives: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\treturn this.extensions.derivatives;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );\n\t\t\t\tthis.extensions.derivatives = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.assign( WebGLRenderer.prototype, {\n\n\t\tsupportsFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \\'OES_texture_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_float' );\n\n\t\t},\n\t\tsupportsHalfFloatTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \\'OES_texture_half_float\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_texture_half_float' );\n\n\t\t},\n\t\tsupportsStandardDerivatives: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \\'OES_standard_derivatives\\' ).' );\n\t\t\treturn this.extensions.get( 'OES_standard_derivatives' );\n\n\t\t},\n\t\tsupportsCompressedTextureS3TC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \\'WEBGL_compressed_texture_s3tc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_s3tc' );\n\n\t\t},\n\t\tsupportsCompressedTexturePVRTC: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \\'WEBGL_compressed_texture_pvrtc\\' ).' );\n\t\t\treturn this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );\n\n\t\t},\n\t\tsupportsBlendMinMax: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \\'EXT_blend_minmax\\' ).' );\n\t\t\treturn this.extensions.get( 'EXT_blend_minmax' );\n\n\t\t},\n\t\tsupportsVertexTextures: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );\n\t\t\treturn this.capabilities.vertexTextures;\n\n\t\t},\n\t\tsupportsInstancedArrays: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \\'ANGLE_instanced_arrays\\' ).' );\n\t\t\treturn this.extensions.get( 'ANGLE_instanced_arrays' );\n\n\t\t},\n\t\tenableScissorTest: function ( boolean ) {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );\n\t\t\tthis.setScissorTest( boolean );\n\n\t\t},\n\t\tinitMaterial: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );\n\n\t\t},\n\t\taddPrePlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );\n\n\t\t},\n\t\taddPostPlugin: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );\n\n\t\t},\n\t\tupdateShadowMap: function () {\n\n\t\t\tconsole.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );\n\n\t\t}\n\n\t} );\n\n\tObject.defineProperties( WebGLRenderer.prototype, {\n\n\t\tshadowMapEnabled: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.enabled;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );\n\t\t\t\tthis.shadowMap.enabled = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapType: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );\n\t\t\t\tthis.shadowMap.type = value;\n\n\t\t\t}\n\t\t},\n\t\tshadowMapCullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.shadowMap.cullFace;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.' );\n\t\t\t\tthis.shadowMap.cullFace = value;\n\n\t\t\t}\n\t\t}\n\t} );\n\n\tObject.defineProperties( WebGLShadowMap.prototype, {\n\n\t\tcullFace: {\n\t\t\tget: function () {\n\n\t\t\t\treturn this.renderReverseSided ? CullFaceFront : CullFaceBack;\n\n\t\t\t},\n\t\t\tset: function ( cullFace ) {\n\n\t\t\t\tvar value = ( cullFace !== CullFaceBack );\n\t\t\t\tconsole.warn( \"WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to \" + value + \".\" );\n\t\t\t\tthis.renderReverseSided = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tObject.defineProperties( WebGLRenderTarget.prototype, {\n\n\t\twrapS: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\treturn this.texture.wrapS;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );\n\t\t\t\tthis.texture.wrapS = value;\n\n\t\t\t}\n\t\t},\n\t\twrapT: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\treturn this.texture.wrapT;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );\n\t\t\t\tthis.texture.wrapT = value;\n\n\t\t\t}\n\t\t},\n\t\tmagFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\treturn this.texture.magFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );\n\t\t\t\tthis.texture.magFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tminFilter: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\treturn this.texture.minFilter;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );\n\t\t\t\tthis.texture.minFilter = value;\n\n\t\t\t}\n\t\t},\n\t\tanisotropy: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\treturn this.texture.anisotropy;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );\n\t\t\t\tthis.texture.anisotropy = value;\n\n\t\t\t}\n\t\t},\n\t\toffset: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\treturn this.texture.offset;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );\n\t\t\t\tthis.texture.offset = value;\n\n\t\t\t}\n\t\t},\n\t\trepeat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\treturn this.texture.repeat;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );\n\t\t\t\tthis.texture.repeat = value;\n\n\t\t\t}\n\t\t},\n\t\tformat: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\treturn this.texture.format;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );\n\t\t\t\tthis.texture.format = value;\n\n\t\t\t}\n\t\t},\n\t\ttype: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\treturn this.texture.type;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );\n\t\t\t\tthis.texture.type = value;\n\n\t\t\t}\n\t\t},\n\t\tgenerateMipmaps: {\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\treturn this.texture.generateMipmaps;\n\n\t\t\t},\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );\n\t\t\t\tthis.texture.generateMipmaps = value;\n\n\t\t\t}\n\t\t}\n\n\t} );\n\n\t//\n\n\tAudio.prototype.load = function ( file ) {\n\n\t\tconsole.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );\n\t\tvar scope = this;\n\t\tvar audioLoader = new AudioLoader();\n\t\taudioLoader.load( file, function ( buffer ) {\n\n\t\t\tscope.setBuffer( buffer );\n\n\t\t} );\n\t\treturn this;\n\n\t};\n\n\tAudioAnalyser.prototype.getData = function () {\n\n\t\tconsole.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );\n\t\treturn this.getFrequencyData();\n\n\t};\n\n\t//\n\n\tvar GeometryUtils = {\n\n\t\tmerge: function ( geometry1, geometry2, materialIndexOffset ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );\n\t\t\tvar matrix;\n\n\t\t\tif ( geometry2.isMesh ) {\n\n\t\t\t\tgeometry2.matrixAutoUpdate && geometry2.updateMatrix();\n\n\t\t\t\tmatrix = geometry2.matrix;\n\t\t\t\tgeometry2 = geometry2.geometry;\n\n\t\t\t}\n\n\t\t\tgeometry1.merge( geometry2, matrix, materialIndexOffset );\n\n\t\t},\n\n\t\tcenter: function ( geometry ) {\n\n\t\t\tconsole.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );\n\t\t\treturn geometry.center();\n\n\t\t}\n\n\t};\n\n\tvar ImageUtils = {\n\n\t\tcrossOrigin: undefined,\n\n\t\tloadTexture: function ( url, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );\n\n\t\t\tvar loader = new TextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( url, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadTextureCube: function ( urls, mapping, onLoad, onError ) {\n\n\t\t\tconsole.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );\n\n\t\t\tvar loader = new CubeTextureLoader();\n\t\t\tloader.setCrossOrigin( this.crossOrigin );\n\n\t\t\tvar texture = loader.load( urls, onLoad, undefined, onError );\n\n\t\t\tif ( mapping ) texture.mapping = mapping;\n\n\t\t\treturn texture;\n\n\t\t},\n\n\t\tloadCompressedTexture: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t},\n\n\t\tloadCompressedTextureCube: function () {\n\n\t\t\tconsole.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );\n\n\t\t}\n\n\t};\n\n\t//\n\n\tfunction Projector() {\n\n\t\tconsole.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' );\n\n\t\tthis.projectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .projectVector() is now vector.project().' );\n\t\t\tvector.project( camera );\n\n\t\t};\n\n\t\tthis.unprojectVector = function ( vector, camera ) {\n\n\t\t\tconsole.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );\n\t\t\tvector.unproject( camera );\n\n\t\t};\n\n\t\tthis.pickingRay = function () {\n\n\t\t\tconsole.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );\n\n\t\t};\n\n\t}\n\n\t//\n\n\tfunction CanvasRenderer() {\n\n\t\tconsole.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' );\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );\n\t\tthis.clear = function () {};\n\t\tthis.render = function () {};\n\t\tthis.setClearColor = function () {};\n\t\tthis.setSize = function () {};\n\n\t}\n\n\texports.WebGLRenderTargetCube = WebGLRenderTargetCube;\n\texports.WebGLRenderTarget = WebGLRenderTarget;\n\texports.WebGLRenderer = WebGLRenderer;\n\texports.ShaderLib = ShaderLib;\n\texports.UniformsLib = UniformsLib;\n\texports.UniformsUtils = UniformsUtils;\n\texports.ShaderChunk = ShaderChunk;\n\texports.FogExp2 = FogExp2;\n\texports.Fog = Fog;\n\texports.Scene = Scene;\n\texports.LensFlare = LensFlare;\n\texports.Sprite = Sprite;\n\texports.LOD = LOD;\n\texports.SkinnedMesh = SkinnedMesh;\n\texports.Skeleton = Skeleton;\n\texports.Bone = Bone;\n\texports.Mesh = Mesh;\n\texports.LineSegments = LineSegments;\n\texports.Line = Line;\n\texports.Points = Points;\n\texports.Group = Group;\n\texports.VideoTexture = VideoTexture;\n\texports.DataTexture = DataTexture;\n\texports.CompressedTexture = CompressedTexture;\n\texports.CubeTexture = CubeTexture;\n\texports.CanvasTexture = CanvasTexture;\n\texports.DepthTexture = DepthTexture;\n\texports.Texture = Texture;\n\texports.CompressedTextureLoader = CompressedTextureLoader;\n\texports.DataTextureLoader = DataTextureLoader;\n\texports.CubeTextureLoader = CubeTextureLoader;\n\texports.TextureLoader = TextureLoader;\n\texports.ObjectLoader = ObjectLoader;\n\texports.MaterialLoader = MaterialLoader;\n\texports.BufferGeometryLoader = BufferGeometryLoader;\n\texports.DefaultLoadingManager = DefaultLoadingManager;\n\texports.LoadingManager = LoadingManager;\n\texports.JSONLoader = JSONLoader;\n\texports.ImageLoader = ImageLoader;\n\texports.FontLoader = FontLoader;\n\texports.FileLoader = FileLoader;\n\texports.Loader = Loader;\n\texports.Cache = Cache;\n\texports.AudioLoader = AudioLoader;\n\texports.SpotLightShadow = SpotLightShadow;\n\texports.SpotLight = SpotLight;\n\texports.PointLight = PointLight;\n\texports.RectAreaLight = RectAreaLight;\n\texports.HemisphereLight = HemisphereLight;\n\texports.DirectionalLightShadow = DirectionalLightShadow;\n\texports.DirectionalLight = DirectionalLight;\n\texports.AmbientLight = AmbientLight;\n\texports.LightShadow = LightShadow;\n\texports.Light = Light;\n\texports.StereoCamera = StereoCamera;\n\texports.PerspectiveCamera = PerspectiveCamera;\n\texports.OrthographicCamera = OrthographicCamera;\n\texports.CubeCamera = CubeCamera;\n\texports.Camera = Camera;\n\texports.AudioListener = AudioListener;\n\texports.PositionalAudio = PositionalAudio;\n\texports.AudioContext = AudioContext;\n\texports.AudioAnalyser = AudioAnalyser;\n\texports.Audio = Audio;\n\texports.VectorKeyframeTrack = VectorKeyframeTrack;\n\texports.StringKeyframeTrack = StringKeyframeTrack;\n\texports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;\n\texports.NumberKeyframeTrack = NumberKeyframeTrack;\n\texports.ColorKeyframeTrack = ColorKeyframeTrack;\n\texports.BooleanKeyframeTrack = BooleanKeyframeTrack;\n\texports.PropertyMixer = PropertyMixer;\n\texports.PropertyBinding = PropertyBinding;\n\texports.KeyframeTrack = KeyframeTrack;\n\texports.AnimationUtils = AnimationUtils;\n\texports.AnimationObjectGroup = AnimationObjectGroup;\n\texports.AnimationMixer = AnimationMixer;\n\texports.AnimationClip = AnimationClip;\n\texports.Uniform = Uniform;\n\texports.InstancedBufferGeometry = InstancedBufferGeometry;\n\texports.BufferGeometry = BufferGeometry;\n\texports.GeometryIdCount = GeometryIdCount;\n\texports.Geometry = Geometry;\n\texports.InterleavedBufferAttribute = InterleavedBufferAttribute;\n\texports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;\n\texports.InterleavedBuffer = InterleavedBuffer;\n\texports.InstancedBufferAttribute = InstancedBufferAttribute;\n\texports.Face3 = Face3;\n\texports.Object3D = Object3D;\n\texports.Raycaster = Raycaster;\n\texports.Layers = Layers;\n\texports.EventDispatcher = EventDispatcher;\n\texports.Clock = Clock;\n\texports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;\n\texports.LinearInterpolant = LinearInterpolant;\n\texports.DiscreteInterpolant = DiscreteInterpolant;\n\texports.CubicInterpolant = CubicInterpolant;\n\texports.Interpolant = Interpolant;\n\texports.Triangle = Triangle;\n\texports.Math = _Math;\n\texports.Spherical = Spherical;\n\texports.Cylindrical = Cylindrical;\n\texports.Plane = Plane;\n\texports.Frustum = Frustum;\n\texports.Sphere = Sphere;\n\texports.Ray = Ray;\n\texports.Matrix4 = Matrix4;\n\texports.Matrix3 = Matrix3;\n\texports.Box3 = Box3;\n\texports.Box2 = Box2;\n\texports.Line3 = Line3;\n\texports.Euler = Euler;\n\texports.Vector4 = Vector4;\n\texports.Vector3 = Vector3;\n\texports.Vector2 = Vector2;\n\texports.Quaternion = Quaternion;\n\texports.Color = Color;\n\texports.MorphBlendMesh = MorphBlendMesh;\n\texports.ImmediateRenderObject = ImmediateRenderObject;\n\texports.VertexNormalsHelper = VertexNormalsHelper;\n\texports.SpotLightHelper = SpotLightHelper;\n\texports.SkeletonHelper = SkeletonHelper;\n\texports.PointLightHelper = PointLightHelper;\n\texports.RectAreaLightHelper = RectAreaLightHelper;\n\texports.HemisphereLightHelper = HemisphereLightHelper;\n\texports.GridHelper = GridHelper;\n\texports.PolarGridHelper = PolarGridHelper;\n\texports.FaceNormalsHelper = FaceNormalsHelper;\n\texports.DirectionalLightHelper = DirectionalLightHelper;\n\texports.CameraHelper = CameraHelper;\n\texports.BoxHelper = BoxHelper;\n\texports.ArrowHelper = ArrowHelper;\n\texports.AxisHelper = AxisHelper;\n\texports.CatmullRomCurve3 = CatmullRomCurve3;\n\texports.CubicBezierCurve3 = CubicBezierCurve3;\n\texports.QuadraticBezierCurve3 = QuadraticBezierCurve3;\n\texports.LineCurve3 = LineCurve3;\n\texports.ArcCurve = ArcCurve;\n\texports.EllipseCurve = EllipseCurve;\n\texports.SplineCurve = SplineCurve;\n\texports.CubicBezierCurve = CubicBezierCurve;\n\texports.QuadraticBezierCurve = QuadraticBezierCurve;\n\texports.LineCurve = LineCurve;\n\texports.Shape = Shape;\n\texports.Path = Path;\n\texports.ShapePath = ShapePath;\n\texports.Font = Font;\n\texports.CurvePath = CurvePath;\n\texports.Curve = Curve;\n\texports.ShapeUtils = ShapeUtils;\n\texports.SceneUtils = SceneUtils;\n\texports.WireframeGeometry = WireframeGeometry;\n\texports.ParametricGeometry = ParametricGeometry;\n\texports.ParametricBufferGeometry = ParametricBufferGeometry;\n\texports.TetrahedronGeometry = TetrahedronGeometry;\n\texports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;\n\texports.OctahedronGeometry = OctahedronGeometry;\n\texports.OctahedronBufferGeometry = OctahedronBufferGeometry;\n\texports.IcosahedronGeometry = IcosahedronGeometry;\n\texports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;\n\texports.DodecahedronGeometry = DodecahedronGeometry;\n\texports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;\n\texports.PolyhedronGeometry = PolyhedronGeometry;\n\texports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;\n\texports.TubeGeometry = TubeGeometry;\n\texports.TubeBufferGeometry = TubeBufferGeometry;\n\texports.TorusKnotGeometry = TorusKnotGeometry;\n\texports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;\n\texports.TorusGeometry = TorusGeometry;\n\texports.TorusBufferGeometry = TorusBufferGeometry;\n\texports.TextGeometry = TextGeometry;\n\texports.SphereGeometry = SphereGeometry;\n\texports.SphereBufferGeometry = SphereBufferGeometry;\n\texports.RingGeometry = RingGeometry;\n\texports.RingBufferGeometry = RingBufferGeometry;\n\texports.PlaneGeometry = PlaneGeometry;\n\texports.PlaneBufferGeometry = PlaneBufferGeometry;\n\texports.LatheGeometry = LatheGeometry;\n\texports.LatheBufferGeometry = LatheBufferGeometry;\n\texports.ShapeGeometry = ShapeGeometry;\n\texports.ShapeBufferGeometry = ShapeBufferGeometry;\n\texports.ExtrudeGeometry = ExtrudeGeometry;\n\texports.EdgesGeometry = EdgesGeometry;\n\texports.ConeGeometry = ConeGeometry;\n\texports.ConeBufferGeometry = ConeBufferGeometry;\n\texports.CylinderGeometry = CylinderGeometry;\n\texports.CylinderBufferGeometry = CylinderBufferGeometry;\n\texports.CircleGeometry = CircleGeometry;\n\texports.CircleBufferGeometry = CircleBufferGeometry;\n\texports.BoxGeometry = BoxGeometry;\n\texports.BoxBufferGeometry = BoxBufferGeometry;\n\texports.ShadowMaterial = ShadowMaterial;\n\texports.SpriteMaterial = SpriteMaterial;\n\texports.RawShaderMaterial = RawShaderMaterial;\n\texports.ShaderMaterial = ShaderMaterial;\n\texports.PointsMaterial = PointsMaterial;\n\texports.MultiMaterial = MultiMaterial;\n\texports.MeshPhysicalMaterial = MeshPhysicalMaterial;\n\texports.MeshStandardMaterial = MeshStandardMaterial;\n\texports.MeshPhongMaterial = MeshPhongMaterial;\n\texports.MeshToonMaterial = MeshToonMaterial;\n\texports.MeshNormalMaterial = MeshNormalMaterial;\n\texports.MeshLambertMaterial = MeshLambertMaterial;\n\texports.MeshDepthMaterial = MeshDepthMaterial;\n\texports.MeshBasicMaterial = MeshBasicMaterial;\n\texports.LineDashedMaterial = LineDashedMaterial;\n\texports.LineBasicMaterial = LineBasicMaterial;\n\texports.Material = Material;\n\texports.Float64BufferAttribute = Float64BufferAttribute;\n\texports.Float32BufferAttribute = Float32BufferAttribute;\n\texports.Uint32BufferAttribute = Uint32BufferAttribute;\n\texports.Int32BufferAttribute = Int32BufferAttribute;\n\texports.Uint16BufferAttribute = Uint16BufferAttribute;\n\texports.Int16BufferAttribute = Int16BufferAttribute;\n\texports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;\n\texports.Uint8BufferAttribute = Uint8BufferAttribute;\n\texports.Int8BufferAttribute = Int8BufferAttribute;\n\texports.BufferAttribute = BufferAttribute;\n\texports.REVISION = REVISION;\n\texports.MOUSE = MOUSE;\n\texports.CullFaceNone = CullFaceNone;\n\texports.CullFaceBack = CullFaceBack;\n\texports.CullFaceFront = CullFaceFront;\n\texports.CullFaceFrontBack = CullFaceFrontBack;\n\texports.FrontFaceDirectionCW = FrontFaceDirectionCW;\n\texports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;\n\texports.BasicShadowMap = BasicShadowMap;\n\texports.PCFShadowMap = PCFShadowMap;\n\texports.PCFSoftShadowMap = PCFSoftShadowMap;\n\texports.FrontSide = FrontSide;\n\texports.BackSide = BackSide;\n\texports.DoubleSide = DoubleSide;\n\texports.FlatShading = FlatShading;\n\texports.SmoothShading = SmoothShading;\n\texports.NoColors = NoColors;\n\texports.FaceColors = FaceColors;\n\texports.VertexColors = VertexColors;\n\texports.NoBlending = NoBlending;\n\texports.NormalBlending = NormalBlending;\n\texports.AdditiveBlending = AdditiveBlending;\n\texports.SubtractiveBlending = SubtractiveBlending;\n\texports.MultiplyBlending = MultiplyBlending;\n\texports.CustomBlending = CustomBlending;\n\texports.AddEquation = AddEquation;\n\texports.SubtractEquation = SubtractEquation;\n\texports.ReverseSubtractEquation = ReverseSubtractEquation;\n\texports.MinEquation = MinEquation;\n\texports.MaxEquation = MaxEquation;\n\texports.ZeroFactor = ZeroFactor;\n\texports.OneFactor = OneFactor;\n\texports.SrcColorFactor = SrcColorFactor;\n\texports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;\n\texports.SrcAlphaFactor = SrcAlphaFactor;\n\texports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;\n\texports.DstAlphaFactor = DstAlphaFactor;\n\texports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;\n\texports.DstColorFactor = DstColorFactor;\n\texports.OneMinusDstColorFactor = OneMinusDstColorFactor;\n\texports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;\n\texports.NeverDepth = NeverDepth;\n\texports.AlwaysDepth = AlwaysDepth;\n\texports.LessDepth = LessDepth;\n\texports.LessEqualDepth = LessEqualDepth;\n\texports.EqualDepth = EqualDepth;\n\texports.GreaterEqualDepth = GreaterEqualDepth;\n\texports.GreaterDepth = GreaterDepth;\n\texports.NotEqualDepth = NotEqualDepth;\n\texports.MultiplyOperation = MultiplyOperation;\n\texports.MixOperation = MixOperation;\n\texports.AddOperation = AddOperation;\n\texports.NoToneMapping = NoToneMapping;\n\texports.LinearToneMapping = LinearToneMapping;\n\texports.ReinhardToneMapping = ReinhardToneMapping;\n\texports.Uncharted2ToneMapping = Uncharted2ToneMapping;\n\texports.CineonToneMapping = CineonToneMapping;\n\texports.UVMapping = UVMapping;\n\texports.CubeReflectionMapping = CubeReflectionMapping;\n\texports.CubeRefractionMapping = CubeRefractionMapping;\n\texports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;\n\texports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;\n\texports.SphericalReflectionMapping = SphericalReflectionMapping;\n\texports.CubeUVReflectionMapping = CubeUVReflectionMapping;\n\texports.CubeUVRefractionMapping = CubeUVRefractionMapping;\n\texports.RepeatWrapping = RepeatWrapping;\n\texports.ClampToEdgeWrapping = ClampToEdgeWrapping;\n\texports.MirroredRepeatWrapping = MirroredRepeatWrapping;\n\texports.NearestFilter = NearestFilter;\n\texports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;\n\texports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;\n\texports.LinearFilter = LinearFilter;\n\texports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;\n\texports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;\n\texports.UnsignedByteType = UnsignedByteType;\n\texports.ByteType = ByteType;\n\texports.ShortType = ShortType;\n\texports.UnsignedShortType = UnsignedShortType;\n\texports.IntType = IntType;\n\texports.UnsignedIntType = UnsignedIntType;\n\texports.FloatType = FloatType;\n\texports.HalfFloatType = HalfFloatType;\n\texports.UnsignedShort4444Type = UnsignedShort4444Type;\n\texports.UnsignedShort5551Type = UnsignedShort5551Type;\n\texports.UnsignedShort565Type = UnsignedShort565Type;\n\texports.UnsignedInt248Type = UnsignedInt248Type;\n\texports.AlphaFormat = AlphaFormat;\n\texports.RGBFormat = RGBFormat;\n\texports.RGBAFormat = RGBAFormat;\n\texports.LuminanceFormat = LuminanceFormat;\n\texports.LuminanceAlphaFormat = LuminanceAlphaFormat;\n\texports.RGBEFormat = RGBEFormat;\n\texports.DepthFormat = DepthFormat;\n\texports.DepthStencilFormat = DepthStencilFormat;\n\texports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;\n\texports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;\n\texports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;\n\texports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;\n\texports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;\n\texports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;\n\texports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;\n\texports.RGB_ETC1_Format = RGB_ETC1_Format;\n\texports.LoopOnce = LoopOnce;\n\texports.LoopRepeat = LoopRepeat;\n\texports.LoopPingPong = LoopPingPong;\n\texports.InterpolateDiscrete = InterpolateDiscrete;\n\texports.InterpolateLinear = InterpolateLinear;\n\texports.InterpolateSmooth = InterpolateSmooth;\n\texports.ZeroCurvatureEnding = ZeroCurvatureEnding;\n\texports.ZeroSlopeEnding = ZeroSlopeEnding;\n\texports.WrapAroundEnding = WrapAroundEnding;\n\texports.TrianglesDrawMode = TrianglesDrawMode;\n\texports.TriangleStripDrawMode = TriangleStripDrawMode;\n\texports.TriangleFanDrawMode = TriangleFanDrawMode;\n\texports.LinearEncoding = LinearEncoding;\n\texports.sRGBEncoding = sRGBEncoding;\n\texports.GammaEncoding = GammaEncoding;\n\texports.RGBEEncoding = RGBEEncoding;\n\texports.LogLuvEncoding = LogLuvEncoding;\n\texports.RGBM7Encoding = RGBM7Encoding;\n\texports.RGBM16Encoding = RGBM16Encoding;\n\texports.RGBDEncoding = RGBDEncoding;\n\texports.BasicDepthPacking = BasicDepthPacking;\n\texports.RGBADepthPacking = RGBADepthPacking;\n\texports.CubeGeometry = BoxGeometry;\n\texports.Face4 = Face4;\n\texports.LineStrip = LineStrip;\n\texports.LinePieces = LinePieces;\n\texports.MeshFaceMaterial = MeshFaceMaterial;\n\texports.PointCloud = PointCloud;\n\texports.Particle = Particle;\n\texports.ParticleSystem = ParticleSystem;\n\texports.PointCloudMaterial = PointCloudMaterial;\n\texports.ParticleBasicMaterial = ParticleBasicMaterial;\n\texports.ParticleSystemMaterial = ParticleSystemMaterial;\n\texports.Vertex = Vertex;\n\texports.DynamicBufferAttribute = DynamicBufferAttribute;\n\texports.Int8Attribute = Int8Attribute;\n\texports.Uint8Attribute = Uint8Attribute;\n\texports.Uint8ClampedAttribute = Uint8ClampedAttribute;\n\texports.Int16Attribute = Int16Attribute;\n\texports.Uint16Attribute = Uint16Attribute;\n\texports.Int32Attribute = Int32Attribute;\n\texports.Uint32Attribute = Uint32Attribute;\n\texports.Float32Attribute = Float32Attribute;\n\texports.Float64Attribute = Float64Attribute;\n\texports.ClosedSplineCurve3 = ClosedSplineCurve3;\n\texports.SplineCurve3 = SplineCurve3;\n\texports.Spline = Spline;\n\texports.BoundingBoxHelper = BoundingBoxHelper;\n\texports.EdgesHelper = EdgesHelper;\n\texports.WireframeHelper = WireframeHelper;\n\texports.XHRLoader = XHRLoader;\n\texports.BinaryTextureLoader = BinaryTextureLoader;\n\texports.GeometryUtils = GeometryUtils;\n\texports.ImageUtils = ImageUtils;\n\texports.Projector = Projector;\n\texports.CanvasRenderer = CanvasRenderer;\n\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three/build/three.js\n// module id = 6\n// module chunks = 0","const THREE = require('three');\r\nconst EffectComposer = require('three-effectcomposer')(THREE)\r\n\r\nexport default function RayMarcher(renderer, scene, camera) {\r\n\t\r\n\tvar target1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);\r\n var composer1 = new EffectComposer(renderer, target1);\r\n var shaderPass1 = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_time: {\r\n type: 'f',\r\n value: 0\r\n },\r\n u_resolution: {\r\n type: 'v2',\r\n value: new THREE.Vector2(window.innerWidth, window.innerHeight)\r\n },\r\n u_fovy: {\r\n type: 'f',\r\n value: camera.fov\r\n },\r\n u_aspect: {\r\n type: 'f',\r\n value: camera.aspect\r\n },\r\n u_cwMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_ccwMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_northMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_southMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_westMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_eastMat: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateX1: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateY1: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateZ1: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateX2: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateY2: {\r\n type: 'm4v',\r\n value: null\r\n },\r\n u_rotateZ2: {\r\n type: 'm4v',\r\n value: null\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/firstPass-frag.glsl')\r\n });\r\n \r\n var composer2 = new EffectComposer(renderer);\r\n var shaderPass2 = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_firstPass: {\r\n \ttype: 't',\r\n \tvalue: null\r\n },\r\n u_previousFrame: {\r\n \ttype: 't',\r\n \tvalue: null\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/secondPass-frag.glsl')\r\n });\r\n shaderPass2.renderToScreen = true;\r\n shaderPass2.material.uniforms.u_firstPass.value = composer1.writeBuffer.texture;\r\n \r\n var target3 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);\r\n var composer3 = new EffectComposer(renderer, target3);\r\n var shaderPass3 = new EffectComposer.ShaderPass({\r\n uniforms: {\r\n u_input: {\r\n \ttype: 't',\r\n \tvalue: null\r\n }\r\n },\r\n vertexShader: require('./glsl/pass-vert.glsl'),\r\n fragmentShader: require('./glsl/thirdPass-frag.glsl')\r\n });\r\n shaderPass2.material.uniforms.u_previousFrame.value = composer3.writeBuffer.texture;\r\n shaderPass3.material.uniforms.u_input.value = composer1.writeBuffer.texture;\r\n \r\n composer1.addPass(shaderPass1);\r\n composer2.addPass(shaderPass2);\r\n composer3.addPass(shaderPass3);\r\n\r\n return {\r\n render: function(buffer, clock) {\r\n shaderPass1.uniforms[\"u_time\"].value = clock.getElapsedTime();\r\n \r\n // Mandelbulb transformation uniforms\r\n var angle = clock.getElapsedTime() / (4.0 * 3.1415); \r\n\r\n var cwMat = new THREE.Matrix4();\r\n cwMat.makeRotationY(angle);\r\n\r\n var ccwMat = new THREE.Matrix4();\r\n ccwMat.makeRotationY(-angle);\r\n\r\n var northMat = new THREE.Matrix4();\r\n northMat.makeRotationX(angle);\r\n\r\n var southMat = new THREE.Matrix4();\r\n southMat.makeRotationX(-angle);\r\n\r\n var eastMat = new THREE.Matrix4();\r\n eastMat.makeRotationZ(angle);\r\n\r\n var westMat = new THREE.Matrix4();\r\n westMat.makeRotationZ(-angle);\r\n\r\n var rotateX1 = new THREE.Matrix4();\r\n rotateX1.makeRotationX(3.1415 / 2.0);\r\n\r\n var rotateY1 = new THREE.Matrix4();\r\n rotateY1.makeRotationY(45.0 * 3.1415 / 180.0);\r\n\r\n var rotateZ1 = new THREE.Matrix4();\r\n rotateZ1.makeRotationZ((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0);\r\n\r\n var rotateX2 = new THREE.Matrix4();\r\n rotateX2.makeRotationX(3.1415 / 2.0);\r\n\r\n var rotateY2 = new THREE.Matrix4();\r\n rotateY2.makeRotationY(-45.0 * 3.1415 / 180.0);\r\n\r\n var rotateZ2 = new THREE.Matrix4();\r\n rotateZ2.makeRotationY((2.0 * clock.getElapsedTime()) * 3.1415 / 180.0);\r\n \r\n shaderPass1.uniforms[\"u_cwMat\"].value = cwMat;\r\n shaderPass1.uniforms[\"u_ccwMat\"].value = ccwMat;\r\n shaderPass1.uniforms[\"u_northMat\"].value = northMat;\r\n shaderPass1.uniforms[\"u_southMat\"].value = southMat;\r\n shaderPass1.uniforms[\"u_westMat\"].value = westMat;\r\n shaderPass1.uniforms[\"u_eastMat\"].value = eastMat;\r\n shaderPass1.uniforms[\"u_rotateX1\"].value = rotateX1;\r\n shaderPass1.uniforms[\"u_rotateY1\"].value = rotateY1;\r\n shaderPass1.uniforms[\"u_rotateZ1\"].value = rotateZ1;\r\n shaderPass1.uniforms[\"u_rotateX2\"].value = rotateX2;\r\n shaderPass1.uniforms[\"u_rotateY2\"].value = rotateY2;\r\n shaderPass1.uniforms[\"u_rotateZ2\"].value = rotateZ2;\r\n \r\n composer1.render();\r\n composer2.render();\r\n composer3.render();\r\n }\r\n }\r\n}\n\n\n// WEBPACK FOOTER //\n// ./src/rayMarching.js","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n var CopyShader = EffectComposer.CopyShader = require('three-copyshader')\n , RenderPass = EffectComposer.RenderPass = require('./lib/renderpass')(THREE)\n , ShaderPass = EffectComposer.ShaderPass = require('./lib/shaderpass')(THREE, EffectComposer)\n , MaskPass = EffectComposer.MaskPass = require('./lib/maskpass')(THREE)\n , ClearMaskPass = EffectComposer.ClearMaskPass = require('./lib/clearmaskpass')(THREE)\n\n function EffectComposer( renderer, renderTarget ) {\n this.renderer = renderer;\n\n if ( renderTarget === undefined ) {\n var width = window.innerWidth || 1;\n var height = window.innerHeight || 1;\n var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };\n\n renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n this.passes = [];\n\n this.copyPass = new ShaderPass( CopyShader );\n };\n\n EffectComposer.prototype = {\n swapBuffers: function() {\n\n var tmp = this.readBuffer;\n this.readBuffer = this.writeBuffer;\n this.writeBuffer = tmp;\n\n },\n\n addPass: function ( pass ) {\n\n this.passes.push( pass );\n\n },\n\n insertPass: function ( pass, index ) {\n\n this.passes.splice( index, 0, pass );\n\n },\n\n render: function ( delta ) {\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n var maskActive = false;\n\n var pass, i, il = this.passes.length;\n\n for ( i = 0; i < il; i ++ ) {\n\n pass = this.passes[ i ];\n\n if ( !pass.enabled ) continue;\n\n pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n if ( pass.needsSwap ) {\n\n if ( maskActive ) {\n\n var context = this.renderer.context;\n\n context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n }\n\n this.swapBuffers();\n\n }\n\n if ( pass instanceof MaskPass ) {\n\n maskActive = true;\n\n } else if ( pass instanceof ClearMaskPass ) {\n\n maskActive = false;\n\n }\n\n }\n\n },\n\n reset: function ( renderTarget ) {\n\n if ( renderTarget === undefined ) {\n\n renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = window.innerWidth;\n renderTarget.height = window.innerHeight;\n\n }\n\n this.renderTarget1 = renderTarget;\n this.renderTarget2 = renderTarget.clone();\n\n this.writeBuffer = this.renderTarget1;\n this.readBuffer = this.renderTarget2;\n\n },\n\n setSize: function ( width, height ) {\n\n var renderTarget = this.renderTarget1.clone();\n\n renderTarget.width = width;\n renderTarget.height = height;\n\n this.reset( renderTarget );\n\n }\n\n };\n\n // shared ortho camera\n\n EffectComposer.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );\n\n EffectComposer.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );\n\n EffectComposer.scene = new THREE.Scene();\n EffectComposer.scene.add( EffectComposer.quad );\n\n return EffectComposer\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/index.js\n// module id = 8\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nmodule.exports = {\n uniforms: {\n \"tDiffuse\": { type: \"t\", value: null },\n \"opacity\": { type: \"f\", value: 1.0 }\n },\n vertexShader: [\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vUv = uv;\",\n \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n \"}\"\n ].join(\"\\n\"),\n fragmentShader: [\n \"uniform float opacity;\",\n\n \"uniform sampler2D tDiffuse;\",\n\n \"varying vec2 vUv;\",\n\n \"void main() {\",\n\n \"vec4 texel = texture2D( tDiffuse, vUv );\",\n \"gl_FragColor = opacity * texel;\",\n\n \"}\"\n ].join(\"\\n\")\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-copyshader/index.js\n// module id = 9\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function RenderPass( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n if (!(this instanceof RenderPass)) return new RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha);\n\n this.scene = scene;\n this.camera = camera;\n\n this.overrideMaterial = overrideMaterial;\n\n this.clearColor = clearColor;\n this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n this.oldClearColor = new THREE.Color();\n this.oldClearAlpha = 1;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n };\n\n RenderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n this.scene.overrideMaterial = this.overrideMaterial;\n\n if ( this.clearColor ) {\n\n this.oldClearColor.copy( renderer.getClearColor() );\n this.oldClearAlpha = renderer.getClearAlpha();\n\n renderer.setClearColor( this.clearColor, this.clearAlpha );\n\n }\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n if ( this.clearColor ) {\n\n renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n }\n\n this.scene.overrideMaterial = null;\n\n }\n\n };\n\n return RenderPass;\n\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/renderpass.js\n// module id = 10\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE, EffectComposer) {\n function ShaderPass( shader, textureID ) {\n if (!(this instanceof ShaderPass)) return new ShaderPass(shader, textureID);\n\n this.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n this.material = new THREE.ShaderMaterial( {\n\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader\n\n } );\n\n this.renderToScreen = false;\n\n this.enabled = true;\n this.needsSwap = true;\n this.clear = false;\n\n };\n\n ShaderPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n if ( this.uniforms[ this.textureID ] ) {\n\n this.uniforms[ this.textureID ].value = readBuffer;\n\n }\n\n EffectComposer.quad.material = this.material;\n\n if ( this.renderToScreen ) {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera );\n\n } else {\n\n renderer.render( EffectComposer.scene, EffectComposer.camera, writeBuffer, this.clear );\n\n }\n\n }\n\n };\n\n return ShaderPass;\n\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/shaderpass.js\n// module id = 11\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function MaskPass( scene, camera ) {\n if (!(this instanceof MaskPass)) return new MaskPass(scene, camera);\n\n this.scene = scene;\n this.camera = camera;\n\n this.enabled = true;\n this.clear = true;\n this.needsSwap = false;\n\n this.inverse = false;\n };\n\n MaskPass.prototype = {\n\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n var context = renderer.context;\n\n // don't update color or depth\n\n context.colorMask( false, false, false, false );\n context.depthMask( false );\n\n // set up stencil\n\n var writeValue, clearValue;\n\n if ( this.inverse ) {\n\n writeValue = 0;\n clearValue = 1;\n\n } else {\n\n writeValue = 1;\n clearValue = 0;\n\n }\n\n context.enable( context.STENCIL_TEST );\n context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n context.clearStencil( clearValue );\n\n // draw into the stencil buffer\n\n renderer.render( this.scene, this.camera, readBuffer, this.clear );\n renderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n // re-enable update of color and depth\n\n context.colorMask( true, true, true, true );\n context.depthMask( true );\n\n // only render where stencil is set to 1\n\n context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n context.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n }\n\n };\n\n return MaskPass\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/maskpass.js\n// module id = 12\n// module chunks = 0","/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nmodule.exports = function(THREE) {\n function ClearMaskPass() {\n if (!(this instanceof ClearMaskPass)) return new ClearMaskPass(scene, camera);\n this.enabled = true;\n };\n\n ClearMaskPass.prototype = {\n render: function ( renderer, writeBuffer, readBuffer, delta ) {\n var context = renderer.context;\n context.disable( context.STENCIL_TEST );\n }\n };\n\n return ClearMaskPass\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-effectcomposer/lib/clearmaskpass.js\n// module id = 13\n// module chunks = 0","module.exports = \"varying vec2 f_uv;\\r\\nvoid main() {\\r\\n f_uv = uv;\\r\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\r\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/pass-vert.glsl\n// module id = 14\n// module chunks = 0","module.exports = \"/* \\r\\n\\tCode written by Joseph Klinger and Tabatha Hickman\\r\\n\\tUniversity of Pennsylvania\\r\\n\\tCIS 700 Instructor: Rachel Hwang\\r\\n\\tMay 2017\\r\\n*/\\r\\n\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 10.0\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform float u_time;\\r\\nuniform vec2 u_resolution;\\r\\nuniform float u_fovy;\\r\\nuniform float u_aspect;\\r\\n\\r\\nuniform mat4 u_cwMat;\\r\\nuniform mat4 u_ccwMat;\\r\\nuniform mat4 u_northMat;\\r\\nuniform mat4 u_southMat;\\r\\nuniform mat4 u_westMat;\\r\\nuniform mat4 u_eastMat;\\r\\nuniform mat4 u_rotateX1;\\r\\nuniform mat4 u_rotateY1;\\r\\nuniform mat4 u_rotateZ1;\\r\\nuniform mat4 u_rotateX2;\\r\\nuniform mat4 u_rotateY2;\\r\\nuniform mat4 u_rotateZ2;\\r\\n\\r\\n\\r\\nvec4 resColor;\\r\\n\\r\\n/***** Geometry SDF Functions\\r\\nhttp://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm\\r\\n\\t\\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t*****/\\r\\n\\r\\nfloat SDF_Sphere( vec3 pos, float radius ) {\\r\\n\\treturn length(pos) - radius;\\r\\n}\\r\\n\\r\\n// Taken from IQ's realtime ShaderToy implementation here: https://www.shadertoy.com/view/ltfSWn\\r\\nfloat SDF_Mandelbulb( vec3 p , float manPower)\\r\\n{\\r\\n\\tvec3 w = p;\\r\\n float m = dot(w,w);\\r\\n\\r\\n vec4 trap = vec4(abs(w),m);\\r\\n float dz = 1.0;\\r\\n \\r\\n \\r\\n for( int i = 0; i < 4; i++ )\\r\\n {\\r\\n#if 1\\r\\n float m2 = m*m;\\r\\n float m4 = m2*m2;\\r\\n dz = manPower*sqrt(m4*m2*m)*dz + 1.0;\\r\\n\\r\\n float x = w.x; float x2 = x*x; float x4 = x2*x2;\\r\\n float y = w.y; float y2 = y*y; float y4 = y2*y2;\\r\\n float z = w.z; float z2 = z*z; float z4 = z2*z2;\\r\\n\\r\\n float k3 = x2 + z2;\\r\\n float k2 = inversesqrt( k3*k3*k3*k3*k3*k3*k3 );\\r\\n float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;\\r\\n float k4 = x2 - y2 + z2;\\r\\n\\r\\n w.x = p.x + 64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2;\\r\\n w.y = p.y + -16.0*y2*k3*k4*k4 + k1*k1;\\r\\n w.z = p.z + -8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2;\\r\\n#else\\r\\n dz = 8.0*pow(m,3.5)*dz + 1.0;\\r\\n \\r\\n float r = length(w);\\r\\n float b = 8.0*acos( clamp(w.y/r, -1.0, 1.0));\\r\\n float a = 8.0*atan( w.x, w.z );\\r\\n w = p + pow(r,8.0) * vec3( sin(b)*sin(a), cos(b), sin(b)*cos(a) );\\r\\n#endif \\r\\n \\r\\n trap = min( trap, vec4(abs(w),m) );\\r\\n\\r\\n m = dot(w,w);\\r\\n if( m > 4.0 )\\r\\n break;\\r\\n }\\r\\n trap.x = m;\\r\\n resColor = trap;\\r\\n\\r\\n return 0.25 * log(m) * sqrt(m) / dz;\\r\\n}\\r\\n\\r\\n// SDF Operators:\\r\\nfloat intersection(float d1, float d2) {\\r\\n return max(d1,d2);\\r\\n}\\r\\n\\r\\nfloat subtraction( float d1, float d2 ) {\\r\\n return max(-d1,d2);\\r\\n}\\r\\n\\r\\nfloat un(float d1, float d2) {\\r\\n return min(d1,d2);\\r\\n}\\r\\n\\r\\n// Returns transformed point based on rotation and translation matrix of shape\\r\\nvec3 transform( vec3 point, mat4 trans ) {\\r\\n\\t//columns of the rotation matrix transpose\\r\\n\\tvec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]);\\r\\n\\tvec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]);\\r\\n\\tvec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]);\\r\\n\\r\\n\\tmat3 rotTranspose = mat3(col1, col2, col3);\\r\\n\\r\\n\\tvec3 col4 = -1.0*rotTranspose*vec3(trans[3]);\\r\\n\\r\\n\\tmat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0));\\r\\n\\r\\n\\treturn vec3(newTrans * vec4(point, 1.0));\\r\\n}\\r\\n\\r\\nfloat mod(int num1, int num2)\\r\\n{\\r\\n\\tint div = num1/num2;\\r\\n\\treturn float(num1 - div*num2);\\r\\n}\\r\\n\\r\\n// Decide which scene to display (time - dependent)\\r\\nint sceneNum()\\r\\n{\\r\\n\\tfloat x = u_time;\\r\\n\\tfloat cycle = 124.0;\\r\\n\\tfloat fps = 6.0;\\r\\n\\tfloat t = mod(x, cycle);\\r\\n\\tif(t <= 42.0) { return 2; }\\r\\n\\telse if(t <= 80.0) { return 1; }\\r\\n\\telse { return 3; }\\r\\n}\\r\\n\\r\\n// Estimate the distance to the objects in the scene depending on the sceneNum() (see above)\\r\\nfloat sceneMap( vec3 pos ) {\\r\\n\\tfloat t = u_time/4.0;\\r\\n\\tint sceneNumber = sceneNum();\\r\\n\\r\\n\\tif(sceneNumber == 1)\\r\\n\\t{\\r\\n\\t\\t//SCENE 01------------------------------------------------------------\\r\\n\\t\\tfloat dist1;\\r\\n\\t\\tvec3 newPos1 = transform(transform(pos + vec3(sin(t)*3.25, sin(t)*2.0, cos(t)*3.25), u_cwMat), u_northMat);\\t\\r\\n\\t\\tfloat bb1 = SDF_Sphere(newPos1, 1.1);\\r\\n\\t\\tif(bb1 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist1 = SDF_Mandelbulb(newPos1, power);\\r\\n\\t\\t}\\t\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist1 = bb1;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist2;\\r\\n\\t\\tvec3 newPos2 = transform(transform(pos + vec3(sin(t + 30.0)*3.25, cos(t + 8.0)*2.0, sin(t)*-1.5), u_ccwMat), u_eastMat);\\t\\r\\n\\t\\tfloat bb2 = SDF_Sphere(newPos2, 1.1);\\r\\n\\t\\tif(bb2 < .015)\\r\\n\\t\\t{\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist2 = SDF_Mandelbulb(newPos2, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist2 = bb2;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\tfloat dist3;\\r\\n\\t\\tvec3 newPos3 = transform(transform(pos + vec3(cos(t+6.0)*3.25, -1.0*sin(t) + -0.5*cos(1.0), sin(t+12.0)*3.25), u_cwMat), u_westMat);\\t\\r\\n\\t\\tfloat bb3 = SDF_Sphere(newPos3, 1.1);\\r\\n\\t\\tif(bb3 < .015)\\r\\n\\t\\t{\\r\\n\\t\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist3 = SDF_Mandelbulb(newPos3, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist3 = bb3;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn un(dist1, un(dist2, dist3));\\r\\n\\t}\\r\\n\\telse if(sceneNumber == 2)\\r\\n\\t{\\r\\n\\t\\t//SCENE 02------------------------------------------------------------\\r\\n\\t\\tfloat dist4;\\r\\n\\t\\tfloat displace = pow(mod(u_time, 124.0)/(42.0), log(0.2) / log(0.5)) * 3.0; \\r\\n\\t\\tvec3 newPos4 = transform(transform(transform(pos + vec3(displace, 0, displace), u_rotateY1), u_rotateZ1), u_rotateX1);\\t\\r\\n\\t\\tfloat bb4 = SDF_Sphere(newPos4, 1.1);\\r\\n\\t\\tif(bb4 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist4 = SDF_Mandelbulb(newPos4, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist4 = bb4;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist4;\\r\\n\\t}\\r\\n\\telse \\r\\n\\t{\\r\\n\\t\\t//SCENE 03------------------------------------------------------------\\r\\n\\t\\tfloat dist5;\\r\\n\\t\\tvec3 newPos5 = transform(transform(transform(pos + vec3(3.0, -1.0, 3.0), u_rotateY2), u_rotateX2), u_rotateZ2);\\t\\r\\n\\t\\tfloat bb5 = SDF_Sphere(newPos5, 1.1);\\r\\n\\t\\tif(bb5 < .015)\\r\\n\\t\\t{\\t\\r\\n\\t\\t\\tfloat power = 10.0;\\r\\n\\t\\t\\tdist5 = SDF_Mandelbulb(newPos5, power);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\tdist5 = bb5;\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\treturn dist5;\\r\\n\\t}\\r\\n}\\r\\n\\r\\nvec3 backgroundColor() {\\r\\n\\tint sn = sceneNum();\\r\\n\\tfloat darken; \\r\\n\\tif(sn == 1)\\r\\n\\t{\\r\\n\\t\\tdarken = abs(cos(sin(8.0*f_uv.x*sin(u_time/12.0) + 8.0) + f_uv.y*2.0));\\r\\n\\t\\tdarken *= abs(sin(cos(4.0*f_uv.y*2.0*sin(u_time/12.0) + 3.0) + f_uv.x*5.0));\\r\\n\\t}\\r\\n\\telse if(sn == 2)\\r\\n\\t{\\r\\n\\t\\tdarken = cos(48.0*length(f_uv - vec2(0.5, 0.5)) + sin(80.0*f_uv.x*-f_uv.y) + cos(50.0*-f_uv.x*f_uv.y) + sin(u_time));\\r\\n\\t}\\r\\n\\telse\\r\\n\\t{\\r\\n\\t\\tdarken = cos(length(f_uv - vec2(0.5, 0.5)));\\r\\n\\t\\tdarken += (0.5 - length(vec2(0.25*f_uv.x + 0.25, f_uv.y) - vec2(0.5, 0.0)))/0.5;\\r\\n\\t}\\r\\n\\t\\r\\n\\tdarken = clamp(darken, 0.2, 1.0);\\r\\n\\r\\n\\tvec3 a = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 b = vec3(0.5, 0.5, 0.5);\\r\\n\\tvec3 c = vec3(2.0, 1.0, 1.0);\\r\\n\\tvec3 d = vec3(0.5, 0.2, 0.25);\\r\\n\\tfloat t = abs(sin(u_time/12.0));\\r\\n\\tvec3 color = a + b*cos(6.28*(c*t + d));\\r\\n\\r\\n\\treturn darken*color;\\r\\n}\\r\\n\\r\\n// Compute the normal of an implicit surface using the gradient method\\r\\n// Note: this method is slightly less accurate than sampling the scene at pos - epsilon, but because that is an expensive operation for the mandelbulb, we avoid it here\\r\\nvec3 computeNormalFast( vec3 pos ) {\\r\\n\\tvec2 point = vec2(0.0001, 0.0);\\r\\n\\tfloat sampleAtPos = sceneMap(pos);\\r\\n\\tvec3 normal = normalize(\\r\\n\\t\\t\\t vec3(sceneMap(pos + point.xyy) - sampleAtPos,\\r\\n\\t\\t\\t\\t\\tsceneMap(pos + point.yxy) - sampleAtPos,\\r\\n\\t\\t\\t\\t\\tsceneMap(pos + point.yyx) - sampleAtPos));\\r\\n\\treturn normal;\\r\\n}\\r\\n\\r\\n// Taken from a presentation by IQ: http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf\\r\\nfloat ComputeAO( vec3 pos, vec3 normal ) {\\r\\n\\tfloat tStep = 0.0025;\\r\\n\\tfloat diff = 0.0;\\r\\n\\tfloat k = 34.0;\\r\\n\\tfor(float i = 1.0; i <= 5.0; i += 1.0) {\\r\\n\\t\\tvec3 sample = pos + (i * tStep) * normal;\\r\\n\\t\\tfloat dist = sceneMap( sample );\\r\\n\\t\\tdiff += pow(0.5, i) * ((i * tStep) - dist);\\r\\n\\t}\\r\\n\\treturn 1.0 - clamp(k * diff, 0.0, 0.9);\\r\\n}\\r\\n\\r\\n// Convert a fragment coordinate to normalized device coordinates\\r\\nvec2 FragCoordToNDC( vec4 fragCoord ) {\\r\\n\\treturn 2.0 * vec2(fragCoord.x / u_resolution.x,\\r\\n\\t\\t\\t\\t\\t fragCoord.y / u_resolution.y) - 1.0;\\r\\n}\\r\\n\\r\\n// Return the direction of a ray cast through the given point in NDC\\r\\n// This function includes the implementation of the camera; changes to the camera should be made here\\r\\nvec3 Raycast( vec2 p_ndc, vec3 cameraPos ) {\\r\\n\\t\\r\\n\\tfloat len = 10.0;\\r\\n\\t\\r\\n\\t// Compute camera's frame of reference\\r\\n\\tvec3 look = normalize(-cameraPos); // Assume we are looking towards (0, 0, 0)\\r\\n\\tvec3 right = normalize(cross(look, vec3(0.0, 1.0, 0.0))); // 0, 1, 0 is the world up vector\\r\\n\\tvec3 up = normalize(cross(right, look));\\r\\n\\t\\r\\n\\tfloat tanAlpha = tan(u_fovy / 2.0);\\r\\n\\tvec3 V = up * len * tanAlpha;\\r\\n\\tvec3 H = right * len * u_aspect * tanAlpha;\\r\\n\\t\\r\\n\\t// Convert x/y components of gl_FragCoord to NDC, then to a world space point\\r\\n\\tvec3 point_World = p_ndc.x * H + p_ndc.y * V;\\r\\n\\t\\r\\n\\t// Return the direction\\r\\n\\treturn normalize(point_World - cameraPos);\\r\\n}\\r\\n\\r\\n// Referencing the following report: http://celarek.at/wp/wp-content/uploads/2014/05/realTimeFractalsReport.pdf\\r\\nvec3 raymarchScene( vec3 origin, vec3 direction ) {\\r\\n\\t// Basic Raymarching function: \\r\\n\\tfloat t = 0.01;\\r\\n\\tvec3 result = vec3(0.0);\\r\\n\\t\\r\\n\\tfor(int i = 1; i <= 750; i++) {\\r\\n\\t\\tfloat dist = sceneMap(origin + t * direction);\\r\\n\\t\\t\\r\\n\\t\\tif(abs(dist) < 0.0002) {\\r\\n\\t\\t\\tresult = vec3(t, float (i) / 1000.0, 1.0);\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t} else if(t > T_MAX) {\\r\\n\\t\\t\\tresult = vec3(T_MAX, float (i) / 1000.0, 0.0);\\r\\n\\t\\t\\tbreak;\\r\\n\\t\\t}\\r\\n\\t\\t\\r\\n\\t\\t#ifdef SPHERE_TRACING\\r\\n\\t\\t\\tt += dist;\\r\\n\\t\\t#else\\r\\n\\t\\t\\tt += 0.01;\\r\\n\\t\\t#endif\\r\\n\\t}\\r\\n\\treturn result;\\r\\n}\\r\\n\\r\\nvoid main() {\\r\\n\\tvec3 cameraPos = vec3(-3.5, 0, -3.5);\\r\\n\\tvec2 point_NDC = FragCoordToNDC(gl_FragCoord);\\r\\n\\tvec3 direction = Raycast(point_NDC, cameraPos);\\r\\n\\t\\r\\n\\tvec3 isect = raymarchScene( cameraPos, direction );\\r\\n\\tvec3 isectPos = cameraPos + isect.x * direction;\\r\\n\\t\\r\\n\\tif(isect.z > 0.0) { // we did intersect with something\\r\\n\\t\\tvec3 normal = computeNormalFast( isectPos );\\r\\n\\t\\tnormal = -normal;\\r\\n\\t\\t\\r\\n\\t\\t// Animated color using orbit traps: see the Mandelbulb SDF by IQ above\\r\\n\\t\\tvec3 trapColor;\\r\\n\\t\\t\\r\\n\\t\\tint sn = sceneNum();\\r\\n\\t\\tif(sn == 1)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(\\r\\n\\t\\t\\t\\tresColor.x-abs(sin((u_time) / 2.0 + isectPos.z) * 0.8), \\r\\n\\t\\t\\t\\tresColor.y-(cos((u_time) / 8.0 + isectPos.y) * 0.5), \\r\\n\\t\\t\\t\\tresColor.z+(cos((u_time) / 2.0 - isectPos.x) * 0.2));\\r\\n\\t\\t}\\r\\n\\t\\telse if(sn == 2)\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(resColor) + vec3(0.4);\\r\\n\\t\\t}\\r\\n\\t\\telse\\r\\n\\t\\t{\\r\\n\\t\\t\\ttrapColor = vec3(0.0, resColor.y + 0.4, resColor.z + 0.4);\\r\\n\\t\\t}\\r\\n\\t\\t\\r\\n\\t\\ttrapColor.r *= 0.01;\\r\\n\\t\\t\\r\\n\\t\\t// Two methods to compute AO:\\r\\n\\t\\t// float ao = ComputeAO(isectPos, normal);\\r\\n\\t\\tfloat fakeAO = 1.0 - clamp(isect.y, 0.0, 0.9);\\r\\n\\t\\t\\r\\n\\t\\t// gl_FragColor = ao * vec4(trapColor, 1);\\r\\n\\t\\tgl_FragColor = fakeAO * vec4(trapColor, 1);\\r\\n\\t} else {\\r\\n\\t\\tgl_FragColor = vec4(backgroundColor(), 1);\\r\\n\\t}\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/firstPass-frag.glsl\n// module id = 15\n// module chunks = 0","module.exports = \"/* \\r\\n\\tCode written by Joseph Klinger and Tabatha Hickman\\r\\n\\tUniversity of Pennsylvania\\r\\n\\tCIS 700 Instructor: Rachel Hwang\\r\\n\\tMay 2017\\r\\n*/\\r\\n\\r\\n#define SPHERE_TRACING true\\r\\n#define T_MAX 12.0\\r\\n#define MOTION_BLUR true\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform sampler2D u_firstPass;\\r\\nuniform sampler2D u_previousFrame;\\r\\n\\r\\n// The sole purpose of this pass is to compute motion blur between the current and previous frames\\r\\nvoid main() {\\r\\n\\t#ifdef MOTION_BLUR\\r\\n\\t\\tfor(float w = 0.0; w <= 1.0; w += 0.2) {\\r\\n\\t\\t\\tgl_FragColor += (1.0 - w) * texture2D(u_firstPass, f_uv) + w * texture2D(u_previousFrame, f_uv);\\r\\n\\t\\t}\\r\\n\\t\\tgl_FragColor /= 1.0 / 0.2; // divide by the number of samples (1 / stepSize)\\r\\n\\t#else\\r\\n\\t\\tgl_FragColor = texture2D(u_firstPass, f_uv);\\r\\n\\t#endif\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/secondPass-frag.glsl\n// module id = 16\n// module chunks = 0","module.exports = \"/* \\r\\n\\tCode written by Joseph Klinger and Tabatha Hickman\\r\\n\\tUniversity of Pennsylvania\\r\\n\\tCIS 700 Instructor: Rachel Hwang\\r\\n\\tMay 2017\\r\\n*/\\r\\n\\r\\nvarying vec2 f_uv;\\r\\n\\r\\nuniform sampler2D u_input;\\r\\n\\r\\nvoid main() {\\r\\n\\tgl_FragColor = texture2D(u_input, f_uv);\\r\\n}\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/glsl/thirdPass-frag.glsl\n// module id = 17\n// module chunks = 0","module.exports = __webpack_public_path__ + \"index.html\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/file-loader?name=[name].[ext]!./index.html\n// module id = 18\n// module chunks = 0","module.exports = function( THREE ) {\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\n\tfunction OrbitControls( object, domElement ) {\n\n\t\tthis.object = object;\n\n\t\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new THREE.Vector3();\n\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = - Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\n\t\t//\n\t\t// public methods\n\t\t//\n\n\t\tthis.getPolarAngle = function () {\n\n\t\t\treturn spherical.phi;\n\n\t\t};\n\n\t\tthis.getAzimuthalAngle = function () {\n\n\t\t\treturn spherical.theta;\n\n\t\t};\n\n\t\tthis.reset = function () {\n\n\t\t\tscope.target.copy( scope.target0 );\n\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\tscope.object.zoom = scope.zoom0;\n\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\tscope.update();\n\n\t\t\tstate = STATE.NONE;\n\n\t\t};\n\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\t\tvar quatInverse = quat.clone().inverse();\n\n\t\t\tvar lastPosition = new THREE.Vector3();\n\t\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\t\treturn function update () {\n\n\t\t\t\tvar position = scope.object.position;\n\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t\t// angle from z-axis around y-axis\n\t\t\t\tspherical.setFromVector3( offset );\n\n\t\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t\t}\n\n\t\t\t\tspherical.theta += sphericalDelta.theta;\n\t\t\t\tspherical.phi += sphericalDelta.phi;\n\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\tspherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );\n\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tspherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );\n\n\t\t\t\tspherical.makeSafe();\n\n\n\t\t\t\tspherical.radius *= scale;\n\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tspherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );\n\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add( panOffset );\n\n\t\t\t\toffset.setFromSpherical( spherical );\n\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\t\tsphericalDelta.theta *= ( 1 - scope.dampingFactor );\n\t\t\t\t\tsphericalDelta.phi *= ( 1 - scope.dampingFactor );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tsphericalDelta.set( 0, 0, 0 );\n\n\t\t\t\t}\n\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\t\tif ( zoomChanged ||\n\t\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\t\tzoomChanged = false;\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\n\t\t\t};\n\n\t\t}();\n\n\t\tthis.dispose = function() {\n\n\t\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel, false );\n\n\t\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t\t};\n\n\t\t//\n\t\t// internals\n\t\t//\n\n\t\tvar scope = this;\n\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\n\t\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\t\tvar state = STATE.NONE;\n\n\t\tvar EPS = 0.000001;\n\n\t\t// current position in spherical coordinates\n\t\tvar spherical = new THREE.Spherical();\n\t\tvar sphericalDelta = new THREE.Spherical();\n\n\t\tvar scale = 1;\n\t\tvar panOffset = new THREE.Vector3();\n\t\tvar zoomChanged = false;\n\n\t\tvar rotateStart = new THREE.Vector2();\n\t\tvar rotateEnd = new THREE.Vector2();\n\t\tvar rotateDelta = new THREE.Vector2();\n\n\t\tvar panStart = new THREE.Vector2();\n\t\tvar panEnd = new THREE.Vector2();\n\t\tvar panDelta = new THREE.Vector2();\n\n\t\tvar dollyStart = new THREE.Vector2();\n\t\tvar dollyEnd = new THREE.Vector2();\n\t\tvar dollyDelta = new THREE.Vector2();\n\n\t\tfunction getAutoRotationAngle() {\n\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t\t}\n\n\t\tfunction getZoomScale() {\n\n\t\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t\t}\n\n\t\tfunction rotateLeft( angle ) {\n\n\t\t\tsphericalDelta.theta -= angle;\n\n\t\t}\n\n\t\tfunction rotateUp( angle ) {\n\n\t\t\tsphericalDelta.phi -= angle;\n\n\t\t}\n\n\t\tvar panLeft = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panLeft( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix\n\t\t\t\tv.multiplyScalar( - distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\tvar panUp = function() {\n\n\t\t\tvar v = new THREE.Vector3();\n\n\t\t\treturn function panUp( distance, objectMatrix ) {\n\n\t\t\t\tv.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix\n\t\t\t\tv.multiplyScalar( distance );\n\n\t\t\t\tpanOffset.add( v );\n\n\t\t\t};\n\n\t\t}();\n\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = function() {\n\n\t\t\tvar offset = new THREE.Vector3();\n\n\t\t\treturn function pan ( deltaX, deltaY ) {\n\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );\n\t\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\t\tscope.enablePan = false;\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t}();\n\n\t\tfunction dollyIn( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale /= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction dollyOut( dollyScale ) {\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\tscale *= dollyScale;\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\n\t\t\t} else {\n\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\t\tscope.enableZoom = false;\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\n\t\tfunction handleMouseDownRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseDownPan( event ) {\n\n\t\t\t//console.log( 'handleMouseDownPan' );\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tfunction handleMouseMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseMovePan( event ) {\n\n\t\t\t//console.log( 'handleMouseMovePan' );\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleMouseUp( event ) {\n\n\t\t\t//console.log( 'handleMouseUp' );\n\n\t\t}\n\n\t\tfunction handleMouseWheel( event ) {\n\n\t\t\t//console.log( 'handleMouseWheel' );\n\n\t\t\tif ( event.deltaY < 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( event.deltaY > 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleKeyDown( event ) {\n\n\t\t\t//console.log( 'handleKeyDown' );\n\n\t\t\tswitch ( event.keyCode ) {\n\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction handleTouchStartRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchStartDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyStart.set( 0, distance );\n\n\t\t}\n\n\t\tfunction handleTouchStartPan( event ) {\n\n\t\t\t//console.log( 'handleTouchStartPan' );\n\n\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t}\n\n\t\tfunction handleTouchMoveRotate( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMoveDolly( event ) {\n\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\n\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\tdollyEnd.set( 0, distance );\n\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tdollyOut( getZoomScale() );\n\n\t\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\t\tdollyIn( getZoomScale() );\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchMovePan( event ) {\n\n\t\t\t//console.log( 'handleTouchMovePan' );\n\n\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\t\tpan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t\tscope.update();\n\n\t\t}\n\n\t\tfunction handleTouchEnd( event ) {\n\n\t\t\t//console.log( 'handleTouchEnd' );\n\n\t\t}\n\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\n\t\tfunction onMouseDown( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseDownRotate( event );\n\n\t\t\t\tstate = STATE.ROTATE;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseDownDolly( event );\n\n\t\t\t\tstate = STATE.DOLLY;\n\n\t\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseDownPan( event );\n\n\t\t\t\tstate = STATE.PAN;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\n\t\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleMouseMoveRotate( event );\n\n\t\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleMouseMoveDolly( event );\n\n\t\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleMouseMovePan( event );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onMouseUp( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleMouseUp( event );\n\n\t\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onMouseWheel( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\thandleMouseWheel( event );\n\n\t\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t}\n\n\t\tfunction onKeyDown( event ) {\n\n\t\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\t\thandleKeyDown( event );\n\n\t\t}\n\n\t\tfunction onTouchStart( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t\tif ( state !== STATE.NONE ) {\n\n\t\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchMove( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tswitch ( event.touches.length ) {\n\n\t\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\n\t\t\t\t\tstate = STATE.NONE;\n\n\t\t\t}\n\n\t\t}\n\n\t\tfunction onTouchEnd( event ) {\n\n\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\thandleTouchEnd( event );\n\n\t\t\tscope.dispatchEvent( endEvent );\n\n\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tfunction onContextMenu( event ) {\n\n\t\t\tevent.preventDefault();\n\n\t\t}\n\n\t\t//\n\n\t\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\t\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.addEventListener( 'wheel', onMouseWheel, false );\n\n\t\tscope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\t\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t\t// force an update at start\n\n\t\tthis.update();\n\n\t};\n\n\tOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n\tOrbitControls.prototype.constructor = OrbitControls;\n\n\tObject.defineProperties( OrbitControls.prototype, {\n\n\t\tcenter: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\t\treturn this.target;\n\n\t\t\t}\n\n\t\t},\n\n\t\t// backward compatibility\n\n\t\tnoZoom: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\treturn ! this.enableZoom;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\t\tthis.enableZoom = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoRotate: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\treturn ! this.enableRotate;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\t\tthis.enableRotate = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoPan: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\treturn ! this.enablePan;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\t\tthis.enablePan = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tnoKeys: {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\treturn ! this.enableKeys;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\t\tthis.enableKeys = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tstaticMoving : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\treturn ! this.enableDamping;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\t\tthis.enableDamping = ! value;\n\n\t\t\t}\n\n\t\t},\n\n\t\tdynamicDampingFactor : {\n\n\t\t\tget: function () {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\treturn this.dampingFactor;\n\n\t\t\t},\n\n\t\t\tset: function ( value ) {\n\n\t\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\t\tthis.dampingFactor = value;\n\n\t\t\t}\n\n\t\t}\n\n\t} );\n\n\treturn OrbitControls;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/three-orbit-controls/index.js\n// module id = 19\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file diff --git a/src/glsl/firstPass-frag.glsl b/src/glsl/firstPass-frag.glsl index 11c56aa4..a9fa8122 100644 --- a/src/glsl/firstPass-frag.glsl +++ b/src/glsl/firstPass-frag.glsl @@ -314,7 +314,7 @@ vec3 raymarchScene( vec3 origin, vec3 direction ) { float t = 0.01; vec3 result = vec3(0.0); - for(int i = 1; i <= 250; i++) { + for(int i = 1; i <= 750; i++) { float dist = sceneMap(origin + t * direction); if(abs(dist) < 0.0002) { @@ -369,11 +369,11 @@ void main() { trapColor.r *= 0.01; // Two methods to compute AO: - float ao = ComputeAO(isectPos, normal); - // float fakeAO = 1.0 - clamp(isect.y, 0.0, 0.9); + // float ao = ComputeAO(isectPos, normal); + float fakeAO = 1.0 - clamp(isect.y, 0.0, 0.9); - gl_FragColor = ao * vec4(trapColor, 1); - // gl_FragColor = fakeAO * vec4(trapColor, 1); + // gl_FragColor = ao * vec4(trapColor, 1); + gl_FragColor = fakeAO * vec4(trapColor, 1); } else { gl_FragColor = vec4(backgroundColor(), 1); }

    wZii{_}XO6uKJMw-*T?H$wr>)6?0z*v# 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

  • 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

    S>dZX6UxApyX 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 yTollMu%c%!8GL*q>$!B0I`!Hxlmr2hDuiBA z1Q8LCni))FL;)$GL&hK=-AIWL0`KF@nGwslXZCx}xA*&9=MU@k%aez!^{jQTd);dV z2Zx;z6c88KuwjFsk>M%J4I4HSH*DB+W!o0ue{xTk`U8J#^tC*5V#D1Q$#LKxo869^ z9pA8_G;YU=Ge7X}?H3Kt`fk`DeEHq4jYH?912=3~D=<2B92w|1#T%*|&(@Tdczn+L#0o}9Y#&2w9i;_@zdF8u+CqMRXXp4CCb zP6ai4m-Rm@;pv{`6^F1M`P{C#UBw-elIVKlp|iN`PhDeHq{mN-96R7&)T3DHOIN`; zDEXUAIhLMrX~owGhgeS~^i;Y~X{(^E2X>lDA~6?PH}NM$uA?L~p}8&=te^3D!e^`{ z6QC6?7}i6)EN)mt9!W^GvBg-roTWd(jewMdm6WVxt*ncTii)AK7&P4-=ZEW1>XO$$ zdYXDtdhFSGC~j-m1J?JwU$2c((Gc#-fuya?Ep~p-r>xUs(;R{xs}&#FY7M!2Gz2r- z_qvW=Hd!AqFjeilr8_+Q$#^Xy7YU* z4bGo@u6NhZcdnxA}B^zKh7zU}aQ zMM5`(QQhlnouL~tGtuGJ>Qomtm9|hOw&#KKBCFh0)uFO9aB2B;8FpmZY{cL5j`xK+ zfu=cFR!s&f_pBV&Z}X1+POU&dN_WgH(fL1Xo&CR?XpTOA7-f4?4VssW?jf+ZyCp% zH#EiT-y%H_*7Ec9i))XL)$4H;29|iejRC9Q9#~x9&MyBnC4!LZmW=j#SP``5I2Go$ zR>$Qq!@_wr<4o`Bz5kev8%pS|xWUw%j`NL{&}{bhT#eatUlxO)chQ{#zP`&h=v7mMI5 z4Qp-KmaGxHwQz}5ZE~Ov`!qcrR|y`1)gsv5tU5eLL>d{I`j*5Rrpbe{t693rgfDp@*qlL&4bXw2YQ+GFzTA4WGV6^|V}xC}iP z(X^joPns~ehqlPR<^Fwj*(L1;1{8iUYcQk@pBslv`G;}-#6RNEerlU3kg_vjrRNu4 zsdgpnFLaCsgjYl(4&ya;&?LM-YNLEGF}39l3^w+1?L%k8+`yx`ovnId-fhFI#prGy zg~sbYs%z_BL9M6=AX6Yz?ki3?)5I=Zn?G%JAw4T7>Tt&^;nF4+@=U};ar$*A$eD5v zy0GdsCMuObRN0^VTwM^^XT8XT>_p-%FPY8NzvAo-8*8F^aYDp8xG}o$UarMZ!V_%U z(#UFZFL>py7Rb%hfjn+>q&`XhhEvLC+D$NsVIYU_>f9fery_CInT>vEkI z3pyt2f44`r)PwGg8&p~}oH|=-?J|qU3UjTdQhKPY?`aXZAHX|dl9reYtb6!JB4?1w z#*$|-NY*R7t8k;0GECCC^Z+K5brmlnVxj~yR=xv0T3YL3;Bt;mp-tc+xN;Ej0IV2# zuv7&TOkbv5!^hyvK